Celery:为什么我需要一个定期任务的代理



我有一个备用脚本,它可以抓取页面,启动到数据库的连接,并将数据库写入其中。我需要它在x小时后定期执行。我可以使用bash脚本,使用伪代码:

while true
do
  python scraper.py
  sleep 60*60*x
done

从我读到的关于消息代理的内容来看,它们用于将"信号"从一个正在运行的程序发送到另一个程序,原则上就像HTTP一样。就像我有一段接受用户电子邮件id的代码一样,它会向另一段发送电子邮件的代码发送带有电子邮件id的信号。

我需要芹菜在heroku上运行定期任务。我已经在一个单独的服务器上有了一个mongodb。为什么我需要为rabbitmq或redis运行另一个服务器?我可以在没有经纪人的情况下使用芹菜吗?

Celery体系结构旨在跨多个服务器扩展和分配任务。对于像你这样的网站来说,这可能有些过头了。通常需要队列服务来维护任务列表并通知已完成任务的状态。

你可能想去休伊看看。Huey是一个小规模的Celery"克隆",只需要Redis作为外部依赖,而不需要RabbitMQ。它仍然使用Redis队列机制来排列队列中的任务。

还有Advanced Python调度器,它甚至不需要Redis,但可以在进程中保持内存中的队列状态。

或者,如果你有少量的周期性任务,没有延迟的任务,我只会使用Cron和纯Python脚本来运行这些任务。

正如Celery文档所解释的:

Celery通过消息进行通信,通常使用代理在客户端和工作人员之间进行调解。为了启动任务,客户端向队列中添加一条消息,然后代理将消息传递给工作人员。

您可以使用现有的MongoDB数据库作为代理。请参阅使用MongoDB。

对于这样的应用程序,最好使用Django后台任务,

安装从PyPI:安装

pip install django-background-tasks

添加到INSTALLED_APPS:

INSTALLED_APPS = (
    # ...
    'background_task',
    # ...
)

迁移数据库:

python manage.py makemigrations background_task
python manage.py migrate

创建和注册任务

要注册任务,请使用后台装饰器:

from background_task import background
from django.contrib.auth.models import User
@background(schedule=60)
def notify_user(user_id):
    # lookup user by id and send them a message
    user = User.objects.get(pk=user_id)
    user.email_user('Here is a notification', 'You have been notified')

这将把notify_user转换为后台任务函数。当您从常规代码中调用它时,它实际上会创建一个Task对象并将其存储在数据库中。然后,数据库包含关于以后实际需要运行哪个函数的串行信息。这确实限制了调用函数时可以传递的参数-它们必须都可以串行化为JSON。因此,为什么在上面的示例中传递user_id而不是user对象。

正常调用notify_user将安排原始函数在60秒后运行:

notify_user(user.id)

这是默认的计划时间(在decorator中设置),但它可以被覆盖:

notify_user(user.id, schedule=90) # 90 seconds from now
notify_user(user.id, schedule=timedelta(minutes=20)) # 20 minutes from now
notify_user(user.id, schedule=timezone.now()) # at a specific time

此外,您现在可以在同步模式下运行原始功能:

notify_user.now(user.id)   # launch a notify_user function and wait for it
notify_user = notify_user.now   # revert task function back to normal function. 

对测试有用。您可以在安排任务时指定详细名称和创建者:

 notify_user(user.id, verbose_name="Notify user", creator=user)

相关内容

  • 没有找到相关文章

最新更新