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は、私が思っていたようには動作しないように見えるので、ここでの答えはまだわかりません。
これが私が使ってきたコードです。 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
セロリ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
もちろん、エラー処理でコードを改善することができます/すべきです...
次は私のために働いた:
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))
セロリがデーモンとして実行されている場合にコマンドラインを使用して同じことを確認するには、
celery -A [app_name] status
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
引数を追加して、あきらめるまで待機する時間を短縮できます。