我对芹菜开发比较陌生,在实现信号方面遇到了问题。 我有一个包含许多不同工作人员的应用程序。 目前,它使用Rabbitmq作为代理,并使用Redis作为后端。
每个工作人员都有自己的队列。这是我们目前配置的方式:
celery = Celery(queueDict['test'], broker=config.REDIS_SERVER, backend=config.REDIS_SERVER)
default_exchange = Exchange('default', type='direct')
test_queue = Queue(queueDict['test'], default_exchange, routing_key=queueDict['test'])
logger = get_task_logger(__name__)
celery.conf.task_queues = (test_queue, )
@celery.task(name='signal2', bind=True)
def signal2(self, param):
print("dog" + param)
我想使用信号,以便能够在应用程序中的任何工作程序上捕获失败的任务。当我在具有task_failure事件的同一个工作程序中使用它时,它将起作用。 但我想让另一个工作人员捕捉这些事件(甚至是我的烧瓶应用程序) 但我似乎缺少了一些东西 这是我目前的尝试。
celery = Celery('consumer', broker=config.REDIS_SERVER, backend=config.REDIS_SERVER)
default_exchange = Exchange('default', type='direct')
default_queue = Queue(queueDict['default'], default_exchange, routing_key=queueDict['default'])
logger = get_task_logger(__name__)
celery.conf.task_queues = (default_queue, )
@task_failure.connect
def process_failure_signal(sender=None, task_id=None, exception=None,
args=None, kwargs=None, traceback=None, einfo=None, **akwargs):
msg = 'Signal exception: %s (%s)' % (
exception.__class__.__name__, exception)
exc_info = (type(exception), exception, traceback)
extra = {
'data': {
'task_id': str(task_id),
'sender': str(sender),
'args': str(args),
'kwargs': str(kwargs),
}
}
logger.error(msg, exc_info=exc_info, extra=extra)
但是它从不接收任何信号... 感谢您的帮助。
答案 0 :(得分:0)
DejanLekic是正确的,他分享的页面正是我想要的。
对于那些感兴趣的人: https://docs.celeryproject.org/en/stable/userguide/monitoring.html#real-time-processing
这可以轻松地用于捕获事件和监视任务。
答案 1 :(得分:0)
要实时处理事件,您需要以下内容
事件使用者(这是Receiver
)
事件进入时调用的一组处理程序。
对于每种事件类型,您可以使用不同的处理程序,也可以使用全部处理程序('*')
状态(可选)
app.events.State
是集群中任务和工作程序的便捷内存表示形式,并随着事件的发生而更新。
它封装了许多常见问题的解决方案,例如检查工作人员是否还活着(通过验证心跳),在事件进入时将事件字段合并在一起,确保时间戳同步等等。
结合这些,您可以轻松地实时处理事件:
from celery import Celery
def my_monitor(app):
state = app.events.State()
def announce_failed_tasks(event):
state.event(event)
# task name is sent only with -received event, and state
# will keep track of this for us.
task = state.tasks.get(event['uuid'])
print('TASK FAILED: %s[%s] %s' % (
task.name, task.uuid, task.info(),))
with app.connection() as connection:
recv = app.events.Receiver(connection, handlers={
'task-failed': announce_failed_tasks,
'*': state.event,
})
recv.capture(limit=None, timeout=None, wakeup=True)
if __name__ == '__main__':
app = Celery(broker='amqp://guest@localhost//')
my_monitor(app)
注意:wakeup
的{{1}}参数向所有工作人员发送信号,以强迫他们发送心跳信号。这样,您可以在监视器启动时立即看到工作人员。
您可以通过指定处理程序来监听特定事件:
capture