检查 celery beat 是不是启动并运行

Posted

技术标签:

【中文标题】检查 celery beat 是不是启动并运行【英文标题】:Check if celery beat is up and running检查 celery beat 是否启动并运行 【发布时间】:2016-05-23 04:48:36 【问题描述】:

在我的 Django 项目中,我使用 Celery 和 Rabbitmq 在后台运行任务。 我正在使用 celery beat 调度程序来运行定期任务。 如何以编程方式检查 celery beat 是否已启动并运行?

【问题讨论】:

你为什么要这样做?发送任务前要检查吗? 如果 celerybeat 没有运行,一个原因是启动故障转移。似乎没有一种公认的方式来实现这一点。 如果是这样,那么最好使用supervisord 或类似的东西。 这是一个真正的问题。最近,我们的一个模块发生了中断,该模块依赖 celery beat 来运行重要的 crons。结果,上周五,几台服务器出现了临时网络中断,其中一台托管了我们的 rabbitmq 安装。一个小时内就恢复了。但是 celery beat,因为它不能进行任何重新连接,导致整个系统实际上是 down 直到星期一早上。即使我现在也在寻找一种可靠的方法来监控它。找到了,但是最新版本不支持python 2.7 github.com/KristianOellegaard/… 【参考方案1】:

定期对 Ping URL 发出 HTTP 请求。当 URL 未按时 ping 通时,URL 监视器会向您发送警报。

import requests
from yourapp.celery_config import app

@app.task
def ping():
    print '[healthcheck] pinging alive status...'
    # healthchecks.io works for me:
    requests.post("https://hchk.io/6466681c-7708-4423-adf0-XXXXXXXXX")

这个celery periodic task 计划每分钟运行一次,如果它没有命中,您的节拍服务已关闭*,监视器将启动您的邮件(或 webhook,以便您可以zapier it 获得移动推送通知)。

celery -A yourapp.celery_config beat -S djcelery.schedulers.DatabaseScheduler

*或不知所措,您应该跟踪任务饱和度,这是 Celery 的噩梦,应该正确检测和解决,当工作人员忙于阻塞需要优化的任务时经常发生

【讨论】:

这是错误的,因为当时工人可能正在停机。 如果您的意思是“hchk.io”可能会关闭,这是真的,那么请依赖类似 aws 的 lambda 函数。如果你的意思是芹菜“工人”没有错,因为如果工人死了,ping 服务将等待他说“我还活着”,否则“它已经死了”,这就是这种服务的重点。跨度> 【参考方案2】:

我最近使用了类似于@panchicore 建议的解决方案来解决同样的问题。

我工作场所的问题是一个使用 celery beat 的重要系统,有时,由于 RabbitMQ 中断,或者我们的服务器和 RabbitMQ 服务器之间的一些连接问题,由于 celery beat 刚刚停止触发 crons,除非重新启动。

由于我们手头没有任何工具,为了监控通过 HTTP 发送的 keep alive 调用,我们使用 statsd 来达到同样的目的。每分钟在 statsd 服务器上增加一个计数器(由 celery 任务完成),然后我们在 grafana 指标上设置电子邮件和松弛通道警报。 (no updates for 10 minutes == outage)

我知道这不是纯粹的程序化方法,但是如果没有单独的监控实体,任何生产级监控/警报都是不完整的。

编程部分尽可能简单。每分钟运行一个小芹菜任务。

@periodic_task(run_every=timedelta(minutes=1))
def update_keep_alive(self):
    logger.info("running keep alive task")
    statsd.incr(statsd_tags.CELERY_BEAT_ALIVE)

我在使用这种方法时遇到的一个问题是由于 UDP 上的 STATSD 数据包丢失。因此,如果可能,请为此目的使用与 STATSD 的 TCP 连接。

【讨论】:

【参考方案3】:

如果您按照celery doc 的教程对 celery 进行了守护,可以通过

来检查它是否正在运行
sudo /etc/init.d/celeryd status
sudo /etc/init.d/celerybeat status

您可以在 python 模块中使用此类命令的返回。

【讨论】:

【参考方案4】:

您可能可以查找supervisor。 它提供了一个celerybeat conf,它记录了与/var/log/celery/beat.log中的节拍相关的所有内容。

解决此问题的另一种方法是使用Flower。您可以为您的服务器设置它(确保其密码受到保护),在 GUI 中更容易注意到正在排队的任务以及它们排队的时间,从而验证您的节拍是否运行良好。

【讨论】:

【参考方案5】:

您可以通过以下命令检查调度程序是否运行

python manage.py celery worker --beat

【讨论】:

@MohammedShareefC 你安装了celery吗?您是否将celery 添加到已安装的应用程序中? @MohammedShareefC 你可以通过运行python manage.py查看可用命令列表 我没有安装 djcelery 应用程序。它解决了这个问题。但是当我安装它时,它开始给出cannot import models 错误指向我的项目代码中的一行。仅当我使用芹菜时才会发生这种情况。【参考方案6】:

您是否使用 upstart 或 supervison 或其他东西来运行 celery workers + celery beat 作为后台任务?在生产中,您应该使用其中之一在后台运行 celery workers + celery beat。

检查 celery beat 的最简单方法是运行:ps aux | grep -i '[c]elerybeat'。如果你得到带有pid 的文本字符串,它正在运行。你也可以让这个命令的输出更漂亮:ps aux | grep -i '[c]elerybeat' | awk 'print $2'。如果你得到号码 - 它正在工作,如果你什么也没得到 - 它不工作。

您还可以查看芹菜工人状态:celery -A projectname status

如果您对高级 celery 监控感兴趣,可以阅读官方文档 monitoring 指南。

【讨论】:

这不是程序化的【参考方案7】:

最近在做一个项目时,我用了这个:

HEALTHCHECK CMD ["stat celerybeat.pid || exit 1"]

本质上,beat 进程会在某个位置(通常是主位置)下写入一个 pid 文件,您所要做的就是获取一些统计信息以检查该文件是否存在。

注意:这在 Docker 容器中启动独立 celery beta 进程时有效

【讨论】:

【参考方案8】:

celery beat/scheduler 的 liveness 目标是检查 celery beat/scheduler 是否能够将作业发送到消息代理,以便相应的消费者可以获取它。 [它还在工作还是处于挂起状态]。 celery worker 和 celery scheduler/beat 可能在也可能不在同一个 pod 或实例中运行。

为了处理这种情况,我们可以创建一个带有装饰器@after_task_publish.connect 的方法update_scheduler_liveness,每次调度程序成功将消息/任务发布到消息代理时都会调用该方法。 每次发布任务成功时,update_scheduler_liveness 方法都会将当前时间戳更新为文件。 在 Liveness 探测中,我们需要使用以下方法检查文件的最后更新时间戳: stat --printf="%Y" celery_beat_schedule_liveness.stat 命令 或者我们可以显式地尝试读取文件(读取模式)并提取时间戳并根据活动探测标准比较时间戳是否是最近的。 在这种方法中,您需要的活跃度标准越多,芹菜节拍触发的工作就越频繁。因此,对于那些工作之间的频率非常大的情况,可以每 2-5 分钟安排一次自定义/专用的 liveness heartbeat 工作,并且消费者可以对其进行处理。 @after_task_publish.connect 装饰器提供了多个参数,这些参数也可用于过滤已触发的活动特定作业

如果我们不想采用基于文件的方法,那么我们可以依赖 Redis 之类的数据源,以及需要在同一行上实现的特定于实例的 redis 键。

【讨论】:

以上是关于检查 celery beat 是不是启动并运行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 celery-beat 启动任务?

使用 Flask 动态调度 Celery Beat 任务

在同一个容器中运行 celery worker + beat

使用 celery-beat 完成上一个任务后,如何在 5 分钟内运行任务?

芹菜不启动多个工人

芹菜节拍不接周期性任务