web-dev-qa-db-ja.com

セロリが利用可能/実行中かどうかを検出する

Celery を使用して非同期タスクを管理しています。ただし、セロリプロセスがダウンして、タスクが実行されない場合があります。セロリの状態を確認し、すべてが正常に機能していることを確認し、問題が検出された場合はエラーメッセージをユーザーに表示できるようにしたいと思います。 Celery Workerのドキュメントからは、このために ping または inspect を使用できるように見えますが、pingはハックを感じ、inspectがどのように使用されるのか明確ではありません(inspect()。registered()が空の場合?)。

これに関するガイダンスをいただければ幸いです。基本的に私が探しているのは次のような方法です:

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

編集:registered()はセロリ2.3.3で利用可能であるようには見えません(2.1ドキュメントにはリストされていますが)。 pingが正しい答えかもしれません。

編集:Pingは、私が思っていたようには動作しないように見えるので、ここでの答えはまだわかりません。

45
Cory

これが私が使ってきたコードです。 celery.task.control.Inspect.stats()は、現在利用可能なワーカーに関する詳細を含む辞書を返します。ワーカーが実行されていない場合はNoneを返し、メッセージブローカーに接続できない場合はIOErrorを発生させます。私はRabbitMQを使用しています-他のメッセージングシステムの動作が若干異なる可能性があります。これはCelery 2.3.xおよび2.4.xで機能しました。どれだけさかのぼるのかわかりません。

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

セロリ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

もちろん、エラー処理でコードを改善することができます/すべきです...

6
Ouss

次は私のために働いた:

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

セロリがデーモンとして実行されている場合にコマンドラインを使用して同じことを確認するには、

  • Virtualenvをアクティブにし、「アプリ」があるディレクトリに移動します
  • 実行してください:celery -A [app_name] status
  • セロリが上がっているかどうかに加えて、いいえが表示されます。ノードのオンライン

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

4
akashbw

anyワーカーが応答しているかどうかをテストする1つの方法は、「ping」ブロードキャストを送信し、最初の応答で成功した結果を返すことです。

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

これは「ping」をブロードキャストし、応答を最大1秒待機します。最初の応答が届くとすぐに、結果が返されます。 Falseの結果をより速くしたい場合は、timeout引数を追加して、あきらめるまで待機する時間を短縮できます。

0
Tim Tisdall