celery 停止任务_Celery 周期任务运行一段时间后意外停止
Celery周期抓取数据
基于Python Django开发了一个网站。为了应对这些需求,在后端系统中引入了分布式任务队列Celery。
应用后, 遇到了一个技术难题:每隔一段时间运行一次的数据刷新时间会在几日前停滞不前, 导致 celery 任务突然无法执行。经过详细排查, 查看日志记录显示: celery_beat进程的日志记录显示其正常更新情况, 然而, celery_worker进程却停留在几日前的状态未有变化。进一步检查系统进程状态发现, 相关进程均处于正常运转状态。面对这一状况感到困惑不解, 经常需要重新启动服务才能解决问题, 而每当遇到类似情况时, 需要重新启动服务才能解决问题, 这种状况断断续续困扰了将近半年的时间
曾经也嫌弃过Python的各种工具不够靠谱,甚至一度考虑转向Java的大本营。稍微想想看的话,换过去也不是没有门槛和成本的。换了之后也会遇到各种各样的问题。如果这个技术栈遇到问题无法解决的话,并不一定换了另一个技术栈也会面临同样的困境。优势在于使用范围广,在于换成小众的技术栈可能会遇到更多困难
那么,想办法解决问题吧。
死锁导致Celery worker卡住无法消费新任务
经过多番查询,在线的一些参考资料中提到了相关信息。其中一个指出,在使用psycopg2与postgres时可能会出现死锁问题。原因在于postgres在使用ssl时会在一个特定的回调函数中设置了一个互斥锁。然而由于该callback是共用的性质 postgres会在卸载连接时自动释放该互斥锁 但由于其他应用程序依赖于该callback并未及时释放导致最终出现死锁现象 解决方法是将psycopg2升级至至少2.6版本及以上
然而我的软件已升至版本2.8。
因此该方案在当前状态下无法普遍应用于我的问题。
尽管如此 但死锁现象仍为我提供了有益的思路。
很可能是celery worker在处理某个任务时出现了停滞现象。
然而我的软件已升至版本2.8。
因此该方案在当前状态下无法普遍应用于我的问题。
尽管如此 但死锁现象仍为我提供了有益的思路。
很可能是celery worker在处理某个任务时出现了停滞现象。
沿着这个线索继续探索吧。
查看死锁原因
OK,查死锁,下面进入debug阶段。
[root@nfvbfqi9 mysite]# celery inspect active
-> celery@nfvbfqi9: OK
这个更新概念的任务已成功提交。
该操作已正确配置并已准备接收数据输入。
所有参数均以默认设置初始化。
此任务将在预设的时间点自动执行。
系统将根据实时数据动态调整参数设置。
{'id': '7cf4a044-bf15-4fc8-a168-c552b393a87b', 'name': 'stockinfo.tasks.clear_django_sessions', 'args': '()', 'kwargs': '{}', 'type': 'stockinfo.tasks.clear_django_sessions', 'hostname': 'celery@nfvbfqi9', 'time_start': 1566252300.1116867, 'acknowledged': True, 'delivery_info': {'exchange': '', 'routing_key': 'celery', 'priority': 0, 'redelivered': False}, 'worker_pid': 2940}
可以观察到有两个任务处于active状态;经过时间转换后发现这些任务的时间点已经是两天前了;由于这些任务的时间点已经是两天前了;因此推测这两个任务可能遇到了瓶颈
在Media相关文章中常使用strace命令来观察进程运行情况。哦,在测试过程中发现我的VPS未预先安装该命令所需的库文件。好吧听起来很经济实惠的做法。其目的是为了显示进程调用栈信息可用cat /proc/{pid}/stack命令实现
[root@nfvbfqi9 mysite]# cat /proc/2939/stack
[] sk_wait_data+0xd9/0xe0
[] tcp_recvmsg+0x2cb/0xe80
[] inet_recvmsg+0x5a/0x90
[] sock_recvmsg+0x133/0x160
[] sys_recvfrom+0xee/0x180
[] system_call_fastpath+0x16/0x1b
[] 0xffffffffffffffff
[root@nfvbfqi9 mysite]# cat /proc/2940/stack
[] pipe_wait+0x5b/0x80
[] pipe_read+0x3e6/0x4e0
[] do_sync_read+0xfa/0x140
[] vfs_read+0xb5/0x1a0
[] sys_read+0x51/0x90
[] system_call_fastpath+0x16/0x1b
[] 0xffffffffffffffff
The task is stuck at tcp_wait_recv_msg. The task is stuck at pipe_wait. The two tasks are both stuck at io_wait.
这两个地方应当避免出现死锁问题;抓取数据时的TCP请求无法避免出现死锁情况。或者建议采取超时机制来处理这种情况。对于PIPE而言,则有可能生产者突然退出导致消费者长时间无法获取数据。
解决方案
IO相关操作设置超时时间。
