芹菜:为什么我需要一个经纪人来执行定期任务?

2024-04-29 09:00:02 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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

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


Tags: 代码程序脚本bashid数据库true信号
3条回答

正如芹菜documentation所解释的:

Celery communicates via messages, usually using a broker to mediate between clients and workers. To initiate a task, a client adds a message to the queue, which the broker then delivers to a worker.

您可以使用现有的MongoDB数据库作为代理。见Using MongoDB

对于这样的应用程序,最好使用Django Background Tasks

安装 从PyPI安装:

pip install django-background-tasks

添加到已安装的应用程序:

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_用户转换为后台任务函数。当您从常规代码调用它时,它实际上会创建一个任务对象并将其存储在数据库中。然后,该数据库包含有关稍后实际需要运行哪个函数的序列化信息。这确实限制了调用函数时可以传递的参数-它们必须都可以序列化为JSON。因此,在上面的示例中,为什么传递的是用户id而不是用户对象。

正常调用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)

芹菜架构旨在跨多个服务器扩展和分配任务。对于像你这样的网站来说,这可能是一个过度的杀戮。通常需要队列服务来维护任务列表并通知已完成任务的状态。

你可能想看看休伊。Huey is small-scale Celery "Clone" needing only Redis as an external dependency,不是拉比特。它仍在使用Redis队列机制将队列中的任务排成一行。

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

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

相关问题 更多 >