web-dev-qa-db-fra.com

Détectez si le céleri est disponible / en cours d'exécution

J'utilise Celery pour gérer les tâches asynchrones. Parfois, cependant, le processus de céleri tombe en panne, ce qui ne provoque l'exécution d'aucune des tâches. Je voudrais pouvoir vérifier l'état du céleri et m'assurer que tout fonctionne bien, et si je détecte des problèmes, afficher un message d'erreur à l'utilisateur. D'après la documentation de Celery Worker, il semble que je pourrais être en mesure d'utiliser ping ou inspect pour cela, mais le ping semble hacky et on ne sait pas exactement comment inspect est destiné à être utilisé (si inspect (). registered () est vide?).

Tout conseil à ce sujet serait apprécié. Fondamentalement, ce que je recherche, c'est une méthode comme celle-ci:

def celery_is_alive():
    from celery.task.control import inspect
    return bool(inspect().registered()) # is this right??

EDIT: Il ne semble même pas que registered () soit disponible sur céleri 2.3.3 (même si la documentation 2.1 le répertorie). Peut-être que ping est la bonne réponse.

EDIT: Ping ne semble pas non plus faire ce que je pensais qu'il ferait, donc toujours pas sûr de la réponse ici.

45
Cory

Voici le code que j'utilise. celery.task.control.Inspect.stats() renvoie un dict contenant beaucoup de détails sur les travailleurs actuellement disponibles, Aucun s'il n'y a aucun travailleur en cours d'exécution, ou lève un IOError s'il ne peut pas se connecter au courtier de messages. J'utilise RabbitMQ - il est possible que d'autres systèmes de messagerie se comportent légèrement différemment. Cela a fonctionné dans Celery 2.3.x et 2.4.x; Je ne sais pas jusqu'où cela remonte.

def get_celery_worker_status():
    ERROR_KEY = "ERROR"
    try:
        from celery.task.control import inspect
        insp = inspect()
        d = insp.stats()
        if not d:
            d = { ERROR_KEY: 'No running Celery workers were found.' }
    except IOError as e:
        from errno import errorcode
        msg = "Error connecting to the backend: " + str(e)
        if len(e.args) > 0 and errorcode.get(e.args[0]) == 'ECONNREFUSED':
            msg += ' Check that the RabbitMQ server is running.'
        d = { ERROR_KEY: msg }
    except ImportError as e:
        d = { ERROR_KEY: str(e)}
    return d
56
Chris Chamberlin

De la documentation de céleri 4.2 :

from your_celery_app import app


def get_celery_worker_status():
    i = app.control.inspect()
    stats = i.stats()
    registered_tasks = i.registered()
    active_tasks = i.active()
    scheduled_tasks = i.scheduled()
    result = {
        'stats': stats,
        'registered_tasks': registered_tasks,
        'active_tasks': active_tasks,
        'scheduled_tasks': scheduled_tasks
    }
    return result

bien sûr, vous pourriez/devriez améliorer le code avec la gestion des erreurs ...

6
Ouss

Ce qui suit a fonctionné pour moi:

import socket
from kombu import Connection

celery_broker_url = "amqp://localhost"

try:
    conn = Connection(celery_broker_url)
    conn.ensure_connection(max_retries=3)
except socket.error:
    raise RuntimeError("Failed to connect to RabbitMQ instance at {}".format(celery_broker_url))
4
Sergey K

Pour vérifier la même chose en utilisant la ligne de commande au cas où céleri s'exécute en tant que démon,

  • Activez virtualenv et allez dans le répertoire où se trouve "l'application"
  • Exécutez maintenant: celery -A [app_name] status
  • Il montrera si le céleri est en place ou non, plus non. de nœuds en ligne

Source: http://michal.karzynski.pl/blog/2014/05/18/setting-up-an-asynchronous-task-queue-for-Django-using-celery-redis/

4
akashbw

Une méthode pour tester si any travailleur répond consiste à envoyer une diffusion "ping" et à retourner avec un résultat réussi sur la première réponse.

from .celery import app  # the celery 'app' created in your project

def is_celery_working():
    result = app.control.broadcast('ping', reply=True, limit=1)
    return bool(result)  # True if at least one result

Cela diffuse un "ping" et attendra jusqu'à une seconde pour les réponses. Dès que la première réponse arrive, elle renvoie un résultat. Si vous voulez un résultat False plus rapidement, vous pouvez ajouter un argument timeout pour réduire le temps d'attente avant d'abandonner.

0
Tim Tisdall