我正在使用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??
编辑:它甚至看起来像芹菜2.3.3上没有注册()(即使2.1文档列出它)。也许ping是正确的答案。
编辑:Ping似乎也没有做我认为会做的事情,所以仍然不确定这里的答案。
答案 0 :(得分:56)
这是我一直在使用的代码。 celery.task.control.Inspect.stats()
返回包含有关当前可用工作程序的大量详细信息的dict,如果没有工作程序正在运行,则返回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
答案 1 :(得分:6)
来自the documentation of celery 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
当然,您可以/应该通过错误处理来改进代码...
答案 2 :(得分:4)
以下对我有用:
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))
答案 3 :(得分:4)
要在celery作为守护程序运行的情况下使用命令行检查相同的内容,
celery -A [app_name] status
答案 4 :(得分:0)
测试任何工作者是否响应的一种方法是发送“ 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”,并且最多等待一秒钟以进行响应。一旦第一个响应进入,它将返回结果。如果您希望更快地获得False
结果,可以添加一个timeout
参数来减少放弃之前等待的时间。
答案 5 :(得分:0)
您可以使用ping
方法来检查任何工人(或特定工人)是否还活着
https://docs.celeryproject.org/en/latest/_modules/celery/app/control.html#Control.ping
celey_app.control.ping()
答案 6 :(得分:0)
以下脚本适用于我。
import boto3
s3 = boto3.client('s3')
s3.delete_object(Bucket="s3bucketname", Key="s3filepath")
答案 7 :(得分:0)
我找到了一个优雅的解决方案:
from .celery import app
try:
app.broker_connection().ensure_connection(max_retries=3)
except Exception as ex:
raise RuntimeError("Failed to connect to celery broker, {}".format(str(ex)))