J'ai exécuté une application flask avec un travailleur de céleri et redis dans trois conteneurs docker séparés sans aucun problème.
Voici comment je le démarre:
celery worker -A app.controller.engine.celery -l info --concurrency=2 --pool eventlet
Le céleri commence bien:
-------------- celery@a828bd5b0089 v4.2.1 (windowlicker)
---- **** -----
--- * *** * -- Linux-4.9.93-linuxkit-aufs-x86_64-with 2018-11-15 16:06:59
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app: app.controller.engine:0x7f8ba4eb70b8
- ** ---------- .> transport: redis://redis:6379/0
- ** ---------- .> results: redis://redis:6379/1
- *** --- * --- .> concurrency: 2 (eventlet)
-- ******* ---- .> task events: ON
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. app.controller.engine.do
INFO:engineio:Server initialized for eventlet.
INFO:engineio:Server initialized for threading.
[2018-11-15 15:44:34,301: INFO/MainProcess] Connected to redis://redis:6379/0
[2018-11-15 15:44:34,321: INFO/MainProcess] mingle: searching for neighbors
[2018-11-15 15:44:35,358: INFO/MainProcess] mingle: all alone
[2018-11-15 15:44:35,396: INFO/MainProcess] pidbox: Connected to redis://redis:6379/0.
[2018-11-15 15:44:35,415: INFO/MainProcess] celery@12af03844cd0 ready.
Mais au démarrage d'une tâche, elle se bloque soudainement:
[2018-11-15 15:02:03,224: CRITICAL/MainProcess] Unrecoverable error: AttributeError("'float' object has no attribute 'items'",)
Traceback (most recent call last):
File "/app/env/lib/python3.6/site-packages/celery/worker/worker.py", line 205, in start
self.blueprint.start(self)
File "/app/env/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
step.start(parent)
File "/app/env/lib/python3.6/site-packages/celery/bootsteps.py", line 369, in start
return self.obj.start()
File "/app/env/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 317, in start
blueprint.start(self)
File "/app/env/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
step.start(parent)
File "/app/env/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 593, in start
c.loop(*c.loop_args())
File "/app/env/lib/python3.6/site-packages/celery/worker/loops.py", line 121, in synloop
connection.drain_events(timeout=2.0)
File "/app/env/lib/python3.6/site-packages/kombu/connection.py", line 301, in drain_events
return self.transport.drain_events(self.connection, **kwargs)
File "/app/env/lib/python3.6/site-packages/kombu/transport/virtual/base.py", line 963, in drain_events
get(self._deliver, timeout=timeout)
File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 359, in get
ret = self.handle_event(fileno, event)
File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 341, in handle_event
return self.on_readable(fileno), self
File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 337, in on_readable
chan.handlers[type]()
File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 724, in _brpop_read
self.connection._deliver(loads(bytes_to_str(item)), dest)
File "/app/env/lib/python3.6/site-packages/kombu/transport/virtual/base.py", line 983, in _deliver
callback(message)
File "/app/env/lib/python3.6/site-packages/kombu/transport/virtual/base.py", line 632, in _callback
self.qos.append(message, message.delivery_tag)
File "/app/env/lib/python3.6/site-packages/kombu/transport/redis.py", line 149, in append
pipe.zadd(self.unacked_index_key, time(), delivery_tag) \
File "/app/env/lib/python3.6/site-packages/redis/client.py", line 2263, in zadd
for pair in iteritems(mapping):
File "/app/env/lib/python3.6/site-packages/redis/_compat.py", line 123, in iteritems
return iter(x.items())
AttributeError: 'float' object has no attribute 'items'
Je ne vois aucune référence à mon code dans la stacktrace.
Voici la méthode de tâche:
@celery.task()
def do(module_name, json_input):
logger.info('____ Running _________________________')
logger.info('testing ***********************')
#modules.run(module_name, json_input)
J'ai commenté l'appel à mon code actuel juste pour vérifier que je ne l'ai pas gâché avec le code de mes modules .. mais il plante quand même.
Quelqu'un a une idée de ce qui pourrait mal se passer ou comment le déboguer correctement?
Merci beaucoup
Le problème était que le conteneur my celery a téléchargé une nouvelle version du package redis avec pip au moment de la construction, éventuellement avec un bogue ou un changement grave qui se bloque lorsque céleri essaie de l'utiliser lors de la connexion à redis. Cette nouvelle bibliothèque redis est la 3.0.0 et elle est sortie aujourd'hui.
Pour résoudre le problème, vous devez spécifier la version précédente dans le fichier requirements.txt (qui est 2.10.6).
Et en fait, la spécification des versions de package dans le fichier requirements.txt est une bonne pratique qui évite ce type de problèmes.
J'ai rencontré ce même problème aujourd'hui. j'espère que cela sera résolu sous peu dans une mise à jour de Celery. Je suis également revenu à une version précédente.
Pas encore assez de représentants pour un commentaire:
Ce problème est suivi par les gens du céleri dans: https://github.com/celery/celery/issues/5175
Menant à ce PR: https://github.com/celery/celery/pull/5176
Qui a été fusionné et rétabli. Parce qu'un autre correctif a atterri. Je ne sais pas si cela a résolu le problème. Ce n'est plus pertinent pour moi.
Pour tous ceux qui utilisent le docker-airflow, j'ai utilisé le folk de puckel/docker-airflow
Il suffit de modifier le dockerfile en ajoutant
&& pip install 'redis>=2.10.5,<3'\
remplacer celery[redis]
avec seulement celery
, en ajoutant du céleri dans le module intégré Apache-airflow, c'est-à-dire
&& pip install Apache-airflow[crypto,celery,postgres,Hive,jdbc,mysql]==$AIRFLOW_VERSION
Mise à jour: Ils ont également changé récemment le fichier docker-airflow dockerfile pour corriger ce bogue, voir ici