我需要帮助解决生产环境中的问题。
我们的设置:
- 由Cherrypy运行的flask应用程序
- Celery处理后台任务
- RabbitMQ作为消息代理(也尝试了redis)
- MySQL for数据库
问题:
一旦Celery正在处理一个任务,并且它运行的时间上级了代理的心跳间隔,代理就关闭连接。一旦任务在Celery中完成处理并且代理停机,它只会重新启动任务。
任务不是幂等的,它们应该运行一次,即使失败也只能运行一次。我没有找到一种方法来防止这种行为,我已经尝试了celery 设置的所有组合。
下面是我的Celery配置:
CELERY = {'broker_url': 'amqp://**:******@127.0.0.1:5672/rdcovhost',
'result_backend': 'rpc://**:******@127.0.0.1:5672/rdcovhost',
'broker_pool_limit': 100, 'broker_connection_timeout': 6000,
'worker_cancel_long_running_tasks_on_connection_loss': True, 'broker_heartbeat': 10,
'broker_transport_options': {'visibility_timeout': 3600}, 'task_ignore_result': True,
'task_publish_retry': False, 'task_acks_late': False}
备注:
- 当然,将心跳增加到一个非常高的值是解决方案的一部分,但不是真实的的解决方案,因为我们希望适应真正的代理间歇性连接
- 将所讨论的任务修改为幂等也是一种解决方案,但可能需要大量时间才能实现,因此肯定有一个简单的解决Celery行为的方法
- 如果Celery worker本身崩溃,则不重复该任务
- 如果代理长时间处于关闭状态,则重新启动该任务
1条答案
按热度按时间fnvucqvd1#
对于那些可能会遇到这个问题的人,我做了以下工作(不是一个最终的解决方案,但被认为是可以接受的生产):
执行此操作的代码: