python分布式定时任务_分布式定时任务的重复执行问题

在Django项目中使用Apscheduler进行分布式定时任务时,由于Gunicorn启动的多进程特性导致任务重复执行。为解决此问题,可以采用幂等性设计、文件锁限制、Gunicorn的--preload参数配合BackgroundScheduler,或者使用Celery实现单一scheduler和多worker执行。这些方案在保证任务正确执行的同时,也考虑了分布式部署的挑战。
摘要由CSDN通过智能技术生成

定时执行某项任务是非常常见的一个需求,简单的 crontabl 就可以完成。我们最近的一个 Django 项目中用了 Apscheduler 来调度定时任务,遇到了一些问题。

首先,Apscheduler 定位是一个依赖于你的应用的任务调度库,非常轻巧:

That APScheduler is not a daemon or service itself, nor does it come with any command line tools. It is primarily meant to be run inside existing applications.

Apscheduler 是跟随你的应用来启动的,没有持久化,没有命令行操作任务的工作,运行在应用的内部(这其中很挫的一个问题是,每次运行 Django manage.py 都会启动这玩意,甚至跑 migrate 都会启动,不过这很可能是我们的用法有问题)。如果一些小巧的项目用起来倒是不错,但是如果需要对任务进行管理和控制,就有很多限制了。

Apscheduler 分布式的问题

我们遇到的问题是:Gunicorn 部署 Django 的时候会起来 4 个进程实例,我们 Django 应用内的 Apscheduler 也会跟着起来 4 个,那么遇到定时制定任务的时候,每个任务都会执行 4 次。这就很蛋疼了。

我们先是用了一个临时的解决方案,就是让任务的执行有幂等性。任务是拉去一部分数据到 MySQL 数据库中,那么就在数据库建立一些 Uniqe 索引,后面重复执行的任务放不进去。这样的做法显然会浪费一些资源,但是从结果上看是可以保证正确的,数据肯定不会被重复存储。缺点是每个任务都要考虑到同步的问题,或是类似的唯一索

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Python实现定时任务的几种方法: 1. 使用while True和time.sleep()函数实现定时任务 ```python import time def some_task(): print("This is a timed task.") while True: some_task() time.sleep(60) # 每隔60秒执行一次任务 ``` 2. 使用threading.Timer定时器实现定时任务 ```python import threading def some_task(): print("This is a timed task.") def timer(): some_task() timer = threading.Timer(60, timer) # 每隔60秒执行一次任务 timer.start() timer() ``` 3. 使用Timeloop库实现定时任务 ```python from timeloop import Timeloop from datetime import timedelta tl = Timeloop() @tl.job(interval=timedelta(seconds=60)) def some_task(): print("This is a timed task.") tl.start(block=True) ``` 4. 使用调度模块sched实现定时任务 ```python import sched import time s = sched.scheduler(time.time, time.sleep) def some_task(): print("This is a timed task.") s.enter(60, 1, some_task, ()) # 每隔60秒执行一次任务 s.enter(60, 1, some_task, ()) s.run() ``` 5. 使用任务框架APScheduler实现定时任务 ```python from apscheduler.schedulers.blocking import BlockingScheduler def some_task(): print("This is a timed task.") scheduler = BlockingScheduler() scheduler.add_job(some_task, 'interval', seconds=60) # 每隔60秒执行一次任务 scheduler.start() ``` 6. 使用分布式消息系统celery执行定时任务 ```python from celery import Celery from datetime import timedelta app = Celery('tasks', broker='pyamqp://guest@localhost//') @app.task def some_task(): print("This is a timed task.") app.conf.beat_schedule = { 'some_task': { 'task': 'tasks.some_task', 'schedule': timedelta(seconds=60), # 每隔60秒执行一次任务 }, } app.conf.timezone = 'UTC' ``` 7. 使用Windows自带的定时任务 在Windows系统中,可以使用计划任务来实现定时任务。具体操作可以参考Windows系统的相关文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值