Versión de apio: 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
El trabajador permanece conectado sin errores
3 minutos después del inicio, el trabajador informa varios errores con un Traceback, similar al siguiente:
[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
Además, el servidor rabbitmq informa de advertencias similares a las siguientes (repetidas dos veces):
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
Tenga en cuenta que cuando se usa prefork
lugar de eventlet
, el servidor rabbitmq aún informa la advertencia de latidos perdidos, pero no hay advertencias impresas en el trabajador:
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
Y gevent
falla con un mensaje de error similar al de 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
Además, puedo confirmar que veo el mismo comportamiento en las últimas versiones de desarrollo de todas las 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
Esto coincide con lo que estamos experimentando. En una sola cola, tenemos varios trabajadores task_acks_late = True
y worker_prefetch_multiplier = 1
y tenemos una combinación de tareas cortas y de larga duración.
Volver a Celery 3.x hace que este problema "desaparezca"
Al principio, los reintentos no funcionaban cuando se usaba apio 4.1.0 y kombu 4.1.0. Después de actualizar tanto a 4.2.0 como a 4.2.1 respectivamente, los reintentos comenzaron a funcionar, pero comenzaron a aparecer los mismos mensajes de tiempo de espera y las tareas parecían ser entregadas correctamente pero nunca procesadas por los trabajadores. 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
La conexión del corredor usa la configuración de latido del archivo de configuración de la aplicación de forma predeterminada (desde la versión 4.2.0
, # 4148).
Configuración y valores predeterminados: documentación
broker_heartbeat
transportes soportados:
- pyamqp
Predeterminado: 120.0 (negociado por el servidor).
Puede intentar configurar broker_heartbeat=0
. Espero que esto ayude.
@ y0ngdi configuré broker_heartbeat=0
, hay una reducción en el error, pero aún 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
Encontré este problema con apio 4.2 y eventlet pero no se encontró una solución perfecta
Hice una pequeña investigación. El apio crea una nueva conexión pero no llama a heartbeat_check
por ella. Esto da como resultado que el servidor RabbitMQ cierre la conexión. He experimentado este error con la conexión del comando (por ejemplo, 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
Intente enviar un comando después de que RabbitMQ haya cerrado la conexión:
$ celery inspect ping
El registro del trabajador de apio imprime esto cuando recibe el 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
Creo que existe una conexión que se termina después del lado del servidor porque kombu.connection.Connection.heartbeat_check()
no se llama repetidamente en la instancia.
Veo el mismo problema con gevent.
La solución con broker_heartbeat = 0
funciona para mí.
Versiones instaladas:
amqp==2.2.2
celery==4.2.0
eventlet==0.23.0
kombu==4.2.1
Obrero:
celery -A celery_app worker --loglevel=info -P eventlet
PS probado en Windows 10, con Python 2 y 3.
@auvipy : ¿Por qué cerrar? El problema no está resuelto ...
¿Funcionó la solución alternativa de @ stojan-jovic?
Parece que sí, pero una solución alternativa no es la corrección de errores.
Y aún así, cada vez más personas pierden mucho tiempo buscando una solución.
si se le ocurre una posible solución, se volverá a abrir.
La solución con broker_heartbeat = 0
parece funcionar para mí para apio 4.2.0 y gevent 1.2.2 (python 2) / RabbitMQ 3.7.8. Al menos no colgó a los trabajadores en el tiempo de espera predeterminado de 60 para mí.
Django 1.8.4, Python 2.7.12
El problema apareció después de la actualización de 3.1.25 a 4.2.1
CELERY_BROKER_HEARTBEAT = 0 en settings.py resolvió esto.
@auvipy, ¿ cerraste esto? El problema aún existe.
@djlambert Es conocido por cerrar problemas / prs sin ningún motivo.
¿Alguna actualización sobre esto? Una solución temporal no es una corrección de errores.
siéntase libre de investigar el problema @gvdmarck mientras se enfrenta a esto, sería más fácil para usted averiguar la causa raíz.
Django 1.8.4, Python 2.7.12
El problema apareció después de la actualización de 3.1.25 a 4.2.1
CELERY_BROKER_HEARTBEAT = 0 en settings.py resolvió esto.
debería ser BROKER_HEARTBEAT en lugar de CELERY_BROKER_HEARTBEAT?
amqp == 2.2.2
Estoy tratando de ejecutar el trabajador de apio con esta configuración, pero el trabajador de apio no se está iniciando.
El comando que estoy usando es el siguiente
pipenv ejecutar apio trabajador -A src.celery_app -l debug -P eventlet
Pero no veo ningún registro de inicio de apio, ni nada que vuelva directamente al indicador de Windows cmd.
@ stojan-jovic, ¿puedes decirme cómo configurar el entorno para el apio?
Comentario más útil
@auvipy, ¿ cerraste esto? El problema aún existe.