Advertisement

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相关操作设置超时时间。

全部评论 (0)

还没有任何评论哟~