Versão de aipo: 4.2.0
docker-compose.yml
version: '2'
services:
worker:
build: .
depends_on:
- rabbitmq
rabbitmq:
image: rabbitmq:alpine
Dockerfile
FROM alpine
RUN apk add --no-cache build-base python3 python3-dev
RUN pip3 install celery eventlet
CMD celery -b amqp://rabbitmq worker -P eventlet --loglevel=DEBUG
$ docker-compose up --build
O trabalhador permanece conectado sem erros
3 minutos após a inicialização, o trabalhador relata vários erros com um Traceback, semelhante ao seguinte:
[2018-06-14 20:11:44,213: WARNING/MainProcess] Traceback (most recent call last):
[2018-06-14 20:11:44,213: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/hubs/poll.py", line 114, in wait
listener.cb(fileno)
[2018-06-14 20:11:44,214: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/celery/worker/pidbox.py", line 120, in loop
connection.drain_events(timeout=1.0)
[2018-06-14 20:11:44,214: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/connection.py", line 301, in drain_events
return self.transport.drain_events(self.connection, **kwargs)
[2018-06-14 20:11:44,215: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/transport/pyamqp.py", line 103, in drain_events
return connection.drain_events(**kwargs)
[2018-06-14 20:11:44,216: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 491, in drain_events
while not self.blocking_read(timeout):
[2018-06-14 20:11:44,217: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 496, in blocking_read
frame = self.transport.read_frame()
[2018-06-14 20:11:44,217: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 243, in read_frame
frame_header = read(7, True)
[2018-06-14 20:11:44,218: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 426, in _read
raise IOError('Socket closed')
[2018-06-14 20:11:44,218: WARNING/MainProcess] OSError: Socket closed
[2018-06-14 20:11:44,219: WARNING/MainProcess] Removing descriptor: 7
Além disso, o servidor rabbitmq relata avisos semelhantes aos seguintes (repetidos duas vezes):
2018-06-14 20:11:44.209 [warning] <0.586.0> closing AMQP connection <0.586.0> (172.19.0.3:42678 -> 172.19.0.2:5672):
missed heartbeats from client, timeout: 60s
Observe que ao usar prefork
vez de eventlet
, o servidor rabbitmq ainda relata o aviso de batimentos cardíacos perdidos, mas não há avisos impressos no trabalhador:
2018-06-14 20:36:04.807 [warning] <0.698.0> closing AMQP connection <0.698.0> (172.19.0.3:46040 -> 172.19.0.2:5672):
missed heartbeats from client, timeout: 60s
E gevent
falha com uma mensagem de erro semelhante a eventlet
:
[2018-06-14 20:43:29,908: WARNING/MainProcess] Traceback (most recent call last):
[2018-06-14 20:43:29,908: WARNING/MainProcess] File "src/gevent/_waiter.py", line 119, in gevent.__waiter.Waiter.switch
[2018-06-14 20:43:29,908: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/celery/worker/pidbox.py", line 120, in loop
connection.drain_events(timeout=1.0)
[2018-06-14 20:43:29,909: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/connection.py", line 301, in drain_events
return self.transport.drain_events(self.connection, **kwargs)
[2018-06-14 20:43:29,909: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/transport/pyamqp.py", line 103, in drain_events
return connection.drain_events(**kwargs)
[2018-06-14 20:43:29,909: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 491, in drain_events
while not self.blocking_read(timeout):
[2018-06-14 20:43:29,910: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 496, in blocking_read
frame = self.transport.read_frame()
[2018-06-14 20:43:29,910: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 243, in read_frame
frame_header = read(7, True)
[2018-06-14 20:43:29,911: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 418, in _read
s = recv(n - len(rbuf))
[2018-06-14 20:43:29,911: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/gevent/_socket3.py", line 380, in recv
return _socket.socket.recv(self._sock, *args)
[2018-06-14 20:43:29,912: WARNING/MainProcess] ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-14 20:43:29,912: WARNING/MainProcess] 2018-06-14T20:43:29Z
[2018-06-14 20:43:29,913: WARNING/MainProcess] <built-in method switch of gevent.__greenlet_primitives.TrackedRawGreenlet object at 0x7f791830ce88> failed with ConnectionResetError
Além disso, posso confirmar que vejo o mesmo comportamento nas versões de desenvolvimento mais recentes de todas as bibliotecas, usando este Dockerfile:
FROM alpine
RUN apk add --no-cache build-base python3 python3-dev
RUN pip3 install https://github.com/celery/celery/zipball/master#egg=celery https://github.com/celery/billiard/zipball/master#egg=billiard https://github.com/celery/py-amqp/zipball/master#egg=amqp https://github.com/celery/kombu/zipball/master#egg=kombu https://github.com/celery/vine/zipball/master#egg=vine eventlet gevent
CMD celery -b amqp://rabbitmq worker -P eventlet --loglevel=DEBUG
Isso corresponde ao que estamos experimentando. Em uma única fila, temos vários trabalhadores task_acks_late = True
e worker_prefetch_multiplier = 1
e temos uma mistura de tarefas de longa e curta duração.
Voltar para o Celery 3.x faz com que esse problema "desapareça"
No início, as novas tentativas não funcionavam ao usar o aipo 4.1.0 e o kombu 4.1.0. Depois de atualizar para 4.2.0 e 4.2.1 respectivamente, as tentativas começaram a funcionar, mas as mesmas mensagens de tempo limite começaram a aparecer e as tarefas pareciam ser entregues corretamente, mas nunca processadas pelos trabalhadores. Estamos usando prefork
-amqp==2.2.2
+amqp==1.4.9
-billiard==3.5.0.3
+billiard==3.3.0.23
-celery==4.2.0
+celery==3.1.23
-kombu==4.2.1
+kombu==3.0.34
-pyramid-celery==3.0.0
+pyramid-celery==2.0.0
A conexão do broker usa a configuração de pulsação do arquivo de configuração do aplicativo por padrão (desde a versão 4.2.0
, # 4148).
Configuração e padrões - Documentação
broker_heartbeat
transportes suportados:
- pyamqp
Padrão: 120,0 (negociado pelo servidor).
Você pode tentar definir broker_heartbeat=0
. Espero que isto ajude.
@ y0ngdi Eu configurei broker_heartbeat=0
, há uma redução no erro, mas ele ainda existe.
amqp==2.3.2
celery==4.2.0
gevent==1.3.4
greenlet==0.4.13
kombu==4.2.0
[2018-06-22 09:41:21,467: INFO/MainProcess] sync with celery<strong i="11">@device_producer_tasks</strong>
[2018-06-22 09:41:21,468: ERROR/MainProcess] Control command error: error(32, 'Broken pipe')
Traceback (most recent call last):
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/celery/worker/pidbox.py", line 46, in on_message
self.node.handle_message(body, message)
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 129, in handle_message
return self.dispatch(**body)
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 112, in dispatch
ticket=ticket)
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 135, in reply
serializer=self.mailbox.serializer)
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/pidbox.py", line 265, in _publish_reply
**opts
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/messaging.py", line 181, in publish
exchange_name, declare,
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/kombu/messaging.py", line 203, in _publish
mandatory=mandatory, immediate=immediate,
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/channel.py", line 1732, in _basic_publish
(0, exchange, routing_key, mandatory, immediate), msg
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/abstract_channel.py", line 50, in send_method
conn.frame_writer(1, self.channel_id, sig, args, content)
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/method_framing.py", line 166, in write_frame
write(view[:offset])
File "/home/ubuntu/.local/share/virtualenvs/backend-uRCQ3Clv/local/lib/python2.7/site-packages/amqp/transport.py", line 275, in write
self._write(s)
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 32] Broken pipe
Encontrei esse problema com o aipo 4.2 e o eventlet, mas nenhuma solução perfeita foi encontrada
Eu fiz uma pequena investigação. O aipo cria uma nova conexão, mas não chama heartbeat_check
para isso. Isso resulta no servidor RabbitMQ fechando a conexão. Eu encontrei este erro com a conexão do comando (por exemplo, stats
, ping
, ..)
from __future__ import absolute_import, unicode_literals
from celery import Celery
app = Celery(
'myapp',
broker='amqp://guest@localhost//',
)
app.conf.broker_heartbeat = 5
if __name__ == '__main__':
app.start()
$ python3 example.py worker -l DEBUG
2018-06-27 19:49:41.109 [info] <0.471.1> accepting AMQP connection <0.471.1> (127.0.0.1:42744 -> 127.0.0.1:5672)
2018-06-27 19:49:41.111 [info] <0.471.1> connection <0.471.1> (127.0.0.1:42744 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-27 19:49:41.116 [info] <0.479.1> accepting AMQP connection <0.479.1> (127.0.0.1:42746 -> 127.0.0.1:5672)
2018-06-27 19:49:41.118 [info] <0.479.1> connection <0.479.1> (127.0.0.1:42746 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-27 19:49:41.131 [info] <0.500.1> accepting AMQP connection <0.500.1> (127.0.0.1:42748 -> 127.0.0.1:5672)
2018-06-27 19:49:41.133 [info] <0.500.1> connection <0.500.1> (127.0.0.1:42748 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-27 19:49:56.135 [warning] <0.500.1> closing AMQP connection <0.500.1> (127.0.0.1:42748 -> 127.0.0.1:5672):
missed heartbeats from client, timeout: 5s
Tente enviar um comando depois que a conexão for fechada pelo RabbitMQ:
$ celery inspect ping
O registro do trabalhador do aipo imprime isso quando recebe o comando:
[2018-06-27 19:51:25,638: DEBUG/MainProcess] pidbox received method ping() [reply_to:{'exchange': 'reply.celery.pidbox', 'routing_key': '5a7fe1f1-be67-397f-879c-d939ea3c076e'} ticket:d80183f3-a236-4057-841b-6b8cd2926917]
[2018-06-27 19:51:25,639: ERROR/MainProcess] Control command error: ConnectionResetError(104, 'Connection reset by peer')
Traceback (most recent call last):
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/celery/worker/pidbox.py", line 46, in on_message
self.node.handle_message(body, message)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 129, in handle_message
return self.dispatch(**body)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 112, in dispatch
ticket=ticket)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 135, in reply
serializer=self.mailbox.serializer)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/pidbox.py", line 265, in _publish_reply
**opts
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 181, in publish
exchange_name, declare,
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 194, in _publish
[maybe_declare(entity) for entity in declare]
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 194, in <listcomp>
[maybe_declare(entity) for entity in declare]
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/messaging.py", line 102, in maybe_declare
return maybe_declare(entity, self.channel, retry, **retry_policy)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/common.py", line 129, in maybe_declare
return _maybe_declare(entity, declared, ident, channel, orig)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/common.py", line 135, in _maybe_declare
entity.declare(channel=channel)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/kombu/entity.py", line 185, in declare
nowait=nowait, passive=passive,
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/channel.py", line 614, in exchange_declare
wait=None if nowait else spec.Exchange.DeclareOk,
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method
conn.frame_writer(1, self.channel_id, sig, args, content)
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame
write(view[:offset])
File "/home/bar/Desktop/foo/virtualenv/lib/python3.6/site-packages/amqp/transport.py", line 275, in write
self._write(s)
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-27 19:51:25,647: DEBUG/MainProcess] Closed channel #2
[2018-06-27 19:51:25,647: DEBUG/MainProcess] using channel_id: 2
[2018-06-27 19:51:25,648: DEBUG/MainProcess] Channel open
Acho que existe uma conexão que é encerrada depois do lado do servidor porque kombu.connection.Connection.heartbeat_check()
não é chamado repetidamente na instância.
Estou vendo o mesmo problema com gevent.
A solução alternativa com broker_heartbeat = 0
funciona para mim.
Versões instaladas:
amqp==2.2.2
celery==4.2.0
eventlet==0.23.0
kombu==4.2.1
Trabalhador:
celery -A celery_app worker --loglevel=info -P eventlet
PS testado em Windows 10, com Python 2 e 3.
@auvipy : Por que fechar? O problema não foi corrigido ...
a solução alternativa @ stojan-jovic funcionou?
Parece que sim, mas uma solução alternativa não é a correção de bugs.
E ainda leva a uma tonelada de tempo desperdiçada procurando uma solução por cada dia mais pessoas.
se você encontrar uma possível correção, ela será reaberta.
A solução alternativa com broker_heartbeat = 0
parece funcionar para mim para o aipo 4.2.0 e gevent 1.2.2 (python 2) / RabbitMQ 3.7.8. Pelo menos não desligou os trabalhadores no tempo limite padrão dos anos 60 para mim.
Django 1.8.4, Python 2.7.12
O problema apareceu após a atualização de 3.1.25 para 4.2.1
CELERY_BROKER_HEARTBEAT = 0 em settings.py resolveu isso.
@auvipy por que você fechou isso? O problema ainda existe.
@djlambert Ele é conhecido por fechar questões / prs sem motivo.
Alguma atualização sobre isso? Uma solução alternativa não é uma correção de bug.
sinta-se à vontade para investigar o problema @gvdmarck, pois você está enfrentando isso, seria mais fácil descobrir a causa raiz.
Django 1.8.4, Python 2.7.12
O problema apareceu após a atualização de 3.1.25 para 4.2.1
CELERY_BROKER_HEARTBEAT = 0 em settings.py resolveu isso.
deve ser BROKER_HEARTBEAT em vez de CELERY_BROKER_HEARTBEAT?
amqp == 2.2.2
Estou tentando executar o trabalho de aipo com esta configuração, mas o trabalho de aipo não está inicializando.
O comando que estou usando é o seguinte
pipenv executar celery worker -A src.celery_app -l debug -P eventlet
Mas não vejo nenhum log de inicialização do aipo ou qualquer coisa que retorne diretamente ao prompt do cmd do Windows.
@ stojan-jovic, você pode me dizer como configurar o ambiente para o aipo.
Comentários muito úteis
@auvipy por que você fechou isso? O problema ainda existe.