Version céleri: 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
Le travailleur reste connecté sans erreur
3 minutes après le démarrage, le worker signale plusieurs erreurs avec un Traceback, semblable à ce qui suit:
[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
De plus, le serveur rabbitmq signale des avertissements similaires aux suivants (répétés deux fois):
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
Notez que lorsque vous utilisez prefork
au lieu de eventlet
, le serveur rabbitmq signale toujours l'avertissement de battements de cœur manqués, mais aucun avertissement n'est imprimé dans le worker:
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
Et gevent
échoue avec un message d'erreur similaire à 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
En outre, je peux confirmer que je vois le même comportement sur les dernières versions de développement de toutes les bibliothèques, en utilisant ce 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
Cela correspond à ce que nous vivons. Sur une seule file d'attente, nous avons plusieurs travailleurs task_acks_late = True
et worker_prefetch_multiplier = 1
et nous avons un mélange de tâches de longue durée et de tâches courtes.
Revenir à Celery 3.x fait «disparaître» ce problème
Au début, les tentatives ne fonctionnaient pas lors de l'utilisation de céleri 4.1.0 et kombu 4.1.0. Après la mise à jour à la fois vers 4.2.0 et 4.2.1 respectivement, les tentatives ont commencé à fonctionner mais les mêmes messages d'expiration ont commencé à apparaître et les tâches semblaient être livrées correctement mais jamais traitées par les travailleurs. Nous utilisons 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 connexion du courtier utilise le paramètre de pulsation du fichier de configuration de l'application par défaut (depuis la version 4.2.0
, # 4148).
Configuration et paramètres par défaut - Documentation
broker_heartbeat
transports pris en charge:
- pyamqp
Par défaut: 120,0 (négocié par le serveur).
Vous pouvez essayer de définir broker_heartbeat=0
. J'espère que cela t'aides.
@ y0ngdi J'ai mis broker_heartbeat=0
, il y a une réduction de l'erreur, mais elle existe toujours.
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
J'ai rencontré ce problème avec céleri 4.2 et eventlet mais aucune solution parfaite n'a été trouvée
J'ai fait une petite enquête. Celery crée une nouvelle connexion mais n'appelle pas heartbeat_check
pour cela. Cela entraîne la fermeture de la connexion par le serveur RabbitMQ. J'ai rencontré cette erreur avec la connexion de commande (par exemple 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
Tentative d'envoi d'une commande après la fermeture de la connexion par RabbitMQ:
$ celery inspect ping
Le journal du céleri l'imprime lorsqu'il reçoit la commande:
[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
Je pense qu'il existe une connexion qui se termine après du côté serveur car kombu.connection.Connection.heartbeat_check()
n'est pas appelé de manière répétitive sur l'instance.
Je vois le même problème avec gevent.
Solution de contournement avec broker_heartbeat = 0
fonctionne pour moi.
Versions installées:
amqp==2.2.2
celery==4.2.0
eventlet==0.23.0
kombu==4.2.1
Ouvrier:
celery -A celery_app worker --loglevel=info -P eventlet
PS Testé sur Windows 10, avec Python 2 et 3.
@auvipy : Pourquoi fermer? Le problème n'est pas résolu ...
la solution de contournement @ stojan-jovic a-t-elle fonctionné?
Il semble que oui, mais une solution de contournement n'est pas une correction de bogue.
Et cela conduit encore à une tonne de temps perdu à chercher une solution par chaque jour plus de gens.
si vous trouvez une solution possible, elle sera rouverte.
La solution de contournement avec broker_heartbeat = 0
semble fonctionner pour moi pour celery 4.2.0 et gevent 1.2.2 (python 2) / RabbitMQ 3.7.8. Au moins, il n'a pas raccroché sur les travailleurs au délai d'expiration par défaut des années 60 pour moi.
Django 1.8.4, Python 2.7.12
Le problème est apparu après la mise à niveau de la version 3.1.25 vers 4.2.1
CELERY_BROKER_HEARTBEAT = 0 dans settings.py a résolu ce problème.
@auvipy pourquoi avez-vous fermé ça? Le problème existe toujours.
@djlambert Il est connu pour fermer les problèmes / prs sans raison.
Des mises à jour à ce sujet? Une solution de contournement n'est pas une correction de bogue.
n'hésitez pas à enquêter sur le problème @gvdmarck car vous y êtes confronté, il vous serait plus facile d'en découvrir la cause.
Django 1.8.4, Python 2.7.12
Le problème est apparu après la mise à niveau de la version 3.1.25 vers 4.2.1
CELERY_BROKER_HEARTBEAT = 0 dans settings.py a résolu ce problème.
devrait être BROKER_HEARTBEAT au lieu de CELERY_BROKER_HEARTBEAT?
amqp == 2.2.2
J'essaye d'exécuter le céleri ouvrier avec cette configuration, mais le céleri ne démarre pas.
La commande que j'utilise est la suivante
pipenv exécuter céleri worker -A src.cellery_app -l debug -P eventlet
Mais je ne vois aucun journal de démarrage de céleri, ni rien qu'il renvoie directement à l'invite cmd de Windows.
@ stojan-jovic, pouvez-vous me dire comment configurer l'environnement pour le céleri.
Commentaire le plus utile
@auvipy pourquoi avez-vous fermé ça? Le problème existe toujours.