这篇文章主要介绍使用复述,实现定时任务多节点部署及自动任务分发的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
执行,且每个任务耗时比较长。我们的生产环境会自动开启三个相同的节点把部署的代码同步运行,这就导致三个节点的定时任务会重复执行,我只好强行关闭另外两个节点,以单节点的方式串行执行定时任务。
这样代码是能跑起来,但是效率低且浪费了另外两个服务器。我需要改造代码以便能支持多节点运行,且能让每个节点分发到不同的任务去执行。
思考过后,我借助复述,实现了一个简单的分布式定时任务,在这里记录一下。
思路
要实现分布式,必须要使用到每个节点都能访问到的公共变量作为全局锁,这里我使用了复述来实现锁。
对每个不同类的任务设置唯一的字符串键,当定时任务开始时,每个节点将会去遍历任务抢占锁,只有获取到锁的节点可以执行锁对应的任务,而未获取到锁的节点将继续遍历其他任务锁,直到所有任务锁被获取并执行。
示例代码:task_manager。py
<>之前从复述,进口Redisfrom apscheduler.schedulers。阻止进口BlockingSchedulerimport timeimport randomr=复述(主机=& # 39;localhost # 39;,端口=6379,德国联邦铁路(db)=0, decode_responses=True) TASK_LIST=[“任务参数1”、“任务参数2”,“任务参数3”,“任务参数4”)#存放当前已完成的集合键FINISHED_TASK_KEY=叭挝?完成“#给每个任务顺序分配不同的复述,键TASK_KEYS=[“任务:{}”.format(任务)的任务范围(len (TASK_LIST))] #复述,键对应的任务参数TASK_MAP={关键:关键任务,任务zip (TASK_KEYS TASK_LIST)}=60 * 60 *到期23 #模拟定时执行的任务,可接受不同的参数def任务(参数): 打印(“- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -”) 打印(“开始执行任务:{}....”.format(参数) time . sleep(随机的。randint (15、30)) 打印(“完成{}“.format(参数) 打印(“- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -”)def开始(): #每日任务开始前先删除复述中已完成任务集合 r.delete (FINISHED_TASK_KEY) #添加复述中唯一任务锁,若添加成功且任务完成表中无当前任务则执行 在TASK_KEYS关键: 状态=r。集(1,关键的前女友=到期,nx=True) #检查当前任务是否已执行 is_finished=r。sismember (FINISHED_TASK_KEY键) 如果状态是真的和is_finished是假的: 打印(“当前节点获取任务:{}成功,准备执行…”.format(关键)) #获取当前复述,键对应的任务参数并执行任务 task_param=TASK_MAP.get(键) 任务(task_param) #任务执行完成将当前任务添加到已完成集合,不允许其他节点再获取该任务 r。大块漂浮植物(FINISHED_TASK_KEY键) r.delete(关键) elif状态是真的和is_finished是正确的: 打印(“未执行:{},其他节点已完成该任务”.format(关键)) 其他: 打印(“未执行:{},其他节点正在执行当前任务”.format(关键))if __name__==& # 39; __main__ # 39;: #这里可使用apscheduler定时任务框架调度开始函数,该处模拟未使用定时任务 start ()模拟多节点运行
先同时打开三个命令行窗口,并键入执行命名,然后尽量相近时间点击回车运行,模拟多节点下定时任务同时触发的场景:
执行情况如下
模拟多节点同步运行结果
根据打印的执行情况看,整体符合预期,一个任务只能被一个节点执行,且能做到自动任务分发,执行完当前任务的节点会自动去获取还未执行的任务,直到所有任务执行完毕。
最后
当然,以上只是一个演示,还需要处理很多异常判断任务,任务完成情况之类的,针对不同的任务情景还可以有其他变通方法。这里只是整理一下思路和分享,希望对你也有所启发。
以上是使用复述,实现定时任务多节点部署及自动任务分发的方法的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!