Closed dalibiao closed 10 months ago
看下你启动代码,是怎么搞得
1.你要发你的启动代码我看看才知道,你用什么job_store类型的apscheduler 2.如果你想粗暴的多次启动定时器,add_push_job中传入run_onceuuid入参就好了.
from funboost.timing_job.apscheduler_use_redis_store import funboost_background_scheduler_redis_store from jobs.job1 import func_a
funboost_background_scheduler_redis_store.start(paused=False) funboost_background_scheduler_redis_store.add_push_job(func_a, trigger='interval', id='99', name='func_a', seconds=10, replace_existing=True)
可以启动呀 这个定时器会每10秒往消息队列里面添加任务, 我启动了两个定时器任务进程, 所以每10秒会添加2个任务. 你是不是看错了, funboost_background_scheduler_redis_store.start(paused=False)这个方法里面paused=False, 会启动, 等于True才不会启动.
也就是你把这个脚本启动了test2.py两次,那肯定是不行的. 因为你把定时任务启动了2次这样.
那这样肯定是重复运行啊,你欧巴定时任务器启动了2次,每个定时任务器都是从redis获取要执行的任务的,你这样肯定不行的
那你要学习apscheduler基本知识了啊,这个和funboost没关系.还是apschduler知识不扎实,但又不按照规定启动
所以我想问的是可不可以实现分布式定时任务, 因为我打算多态机器部署定时任务, apscheduler我之前接触过, 好像也不支持. 只能自定义分布式锁了. 我要问一下大牛有什么好的实现方案.
如果你想动态修改定时任务,应该是在修改脚本里面 puased=True, 在启动定时任务的脚本里面 paused=False,这个文档有讲解.
属于apscheduler的基本知识了
当然可以分布式的啊,你add_push_job 传入 runonce_uuid,那就随便你去无数次 apscheduler.start(paused=False) 了.
你不需要分布式的多次运行apscheduler.start(paused=False) 启动定时任务啊,哎,你只需要apscheduler.start(paused=False) 一次就行了,别的地方改成paused=True. 你还是没理解定时任务在funboost中的角色.
apscheduler是负责定时任务发布消息到一个消息队列中,发布一条消息只要1毫秒,快得很, apscherulder吧消息发到消息队列后,由funboost执行函数消息本身,funboost来执行耗时任务,apscheduler只是执行个推送消息而已,所以你担心apscheduler的性能差需要分布式,那是完全是想多了.
apscheduler在funboost中不会存在性能问题啊,他又不负责执行函数本身,为什么你非要把apscheduler来 apscheduler.start(paused=False) 在多台机器上运行呢, funboost才是执行函数需要消耗性能.
感觉你没有理解apscheduler在funboost中的作用,以为apscheduler需要执行重型函数,apscheduler只是发布一条消息到消息队列.任务非常轻
funboost+apscheduler这个和celery的定时任务一样的概念,定时任务只是负责定时把函数入参发到消息队列而已,并不负责直接执行函数啊.
考虑的场景不一样, 公司部署需要考虑容灾性, 如果定时器启动程序只在一台服务器上面. 如果这台服务器出现宕机, 定时器不就挂了. 现在的问题其实和funboost关系不大, 你说的原理我都知道, 我以前使用apscheduler和celery搭建的单机定时任务系统嵌入在flask里面
定时任务吧消息定时发布到消息队列中,funboost多台机器分布式部署从一个消息队列拉取消息,funboost才是执行函数和入参
考虑的场景不一样, 公司部署需要考虑容灾性, 如果定时器启动程序只在一台服务器上面. 如果这台服务器出现宕机, 定时器不就挂了. 现在的问题其实和funboost关系不大, 你说的原理我都知道, 我以前使用apscheduler和celery搭建的单机定时任务系统嵌入在flask里面
你这个也好办,你自己传入runonce_uuid可以阻止重复发布, 或者你在你的函数内部自己加redis过滤,不执行相同任务.
你看看这个
我知道你是把apscheduler当做定时器推送任务, 和celery-beat类似, 如果funboost集成到flask项目中, funboost_background_scheduler_redis_store定时器需要单独启动, 还是随着flask app一起启动呢.
另外加上runonce_uuid参数定时器就只会推一次任务进去了, 之后就不会push任务进去..... 定时器是不是应该在push任务之后删除runonce_uuid参数, 目的是同一个任务不会在同一时刻推送多次到任务队列里面
1/ 如果你要从前端页面中请求flask来动态增删改定时任务,flask脚本里面肯定要启动定时任务的,但是务必设置apscheduler.start(paused=True), 如果你不执行start,你是无法增删改定时任务的. 2/ funboost_background_scheduler_redis_store还需要单独启动一次 .start(paused=false)
3/关于过滤重复任务,你可以不阻止重复推送,只阻止重复消费就行了.funboost 自带了入参过滤功能,并且可以设置多久时间之内过滤失效. 这些redis分布式过滤逻辑你也可以写在你的函数里面也行
还有一个问题, boost的入参queue_name在装饰每一个函数都要是唯一的吗? 如何每一个函数都要设置一个queue_name, 如果有100个函数, 那在启动所有任务的时候是不是要python funboost_cli_user.py --booster_dirs_str=jobs consume q1 q2 q3....q100, 写100个queue_name, 有没有快捷的部署指令
funboost不需要命令行部署,可以直接运行的,命令行不是必需品.
你自己for循环,把每个booster.consume也可以啊.
queue_name最好是每个函数唯一的,不然的不同函数消息入参不一样,运行出错.
文档第12章的在命令行敲击一大串字符串启动消费是个鸡肋,不如启动一个python文件
建议搞一个一键启动所用任务的方法, 类似于celery启动命令一样. 会自动寻找所有task
早就有了.
你的消费函数很多吗,一般也就几十个吧最多
消费函数很多, 几百个... 可能是我设计的不太合理, 每一个异步方法都搞成了一个消费函数. 另外如果我开启了do_task_filtering执行任务会报一下错误, 是不是哪里设置不对...
日志应该记录有错误堆栈的,不止错误描述
这个地方,稍等,有效期的过滤,有个bug.之前按redis2版本开发的,redis3版本改了,我要改下.
安装30.4版本 pip install funboost -i https://pypi.org/simple
不过不建议用有效期过滤来房子重复运行,过滤是函数运行成功后才添加到redis的zset里面,你函数如果耗时2秒,那还是重复运行的,你可以在你的消费函数里面加sleep测试就能验证了.
你自己在函数里面加redis逻辑吧,这个不难
cahtgtp已经告诉你5种方式房子定时任务重复运行了.
不过不建议用有效期过滤来房子重复运行,过滤是函数运行成功后才添加到redis的zset里面,你函数如果耗时2秒,那还是重复运行的,你可以在你的消费函数里面加sleep测试就能验证了.
你自己在函数里面加redis逻辑吧,这个不难 我重写了一下push_fun_params_to_broker, 这样就可以保证任务只会执行一次了.
你这样加肯定不行啊,托女裤子放屁那不是.那另外一个脚本不是又能发布了
你sadd马上又删除了,那还不是可以重复发布.
我说的是你自己在你的消费函数里面增加redis的逻辑啊,不需要改动funboost源码.
我说的是你自己在你的消费函数里面增加redis的逻辑啊,不需要改动funboost源码.
我没有改源码呀, 我是重写的一个方法, 测试过是可以解决同一时刻一个任务只运行一次. 现在这种实现简单粗暴, 我再优化一下
如果启动多个定时任务进程, 同一个任务会重复执行.