关于 django 使用 apscheduler 一次任务被重复执行问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanne
V2EX    Django

关于 django 使用 apscheduler 一次任务被重复执行问题

  •  
  •   fanne 2018-01-15 17:17:43 +08:00
    这是一个创建于 2855 天前的主题,其中的信息可能已经有所发展或是发生改变。

    APSwork 部分内容

    redis_cOnnet= redis.Redis(host='localhost', port=6379, db=0) jobstores = { 'redis': RedisJobStore(), } executors = { 'default': ThreadPoolExecutor(4) } sched = BackgroundScheduler(jobstores=jobstores, executors=executors) def open_in(servername,serverip,cmd): print '{0}--open in ....'.format(servername) ..... def open_out(servername,serverip,cmd): print '{0}---open out ....'.format(servername) ..... def cronKaifu(starttime,servername,serverip,cmd_in,cmd_out): .... jobstores = { 'redis': RedisJobStore(), } executors = { 'default': ThreadPoolExecutor(1) # 'processpool': ProcessPoolExecutor(3) } sched = BackgroundScheduler(jobstores=jobstores, executors=executors) sched.add_job(func=open_in,args=(servername,serverip,cmd_in,),trigger='date',next_run_time=open_in_time,jobstore='redis',id='{0}_in_{1}'.format(servername,sendtime_timestamp_in)) print sched.get_jobs() sched.add_job(func=open_out,args=(servername,serverip,cmd_out,),trigger='date',next_run_time=open_out_time,jobstore='redis',id='{0}_out_{1}'.format(servername,sendtime_timestamp_out)) print sched.get_jobs() sched.start() 

    views.py 里面调用这个任务

    def kaifu_time(request): .... .... cronKaifu(timeArray,server_name,server_ip,open_in_cmd,open_out_cmd) ...... .... return render(request, 'mt/kaifu_time.html', locals()) 

    添加任务后,两次打印 get_jobs()内容

    [<Job (id=mt_ios999game_in_1516005540000 name=open_in)>] [<Job (id=mt_ios999game_in_1516005540000 name=open_in)>, <Job (id=mt_ios999game_out_1516006260000 name=open_out)>] 

    到点后,id=mt_ios999game_in_1516005540000,会被执行 2 次,有时候会是 3 次,但有时候又是正常的。

    [15/Jan/2018 15:02:22] "POST /mt/kaifu_time/ HTTP/1.1" 302 0 [15/Jan/2018 15:02:22] "GET /mt/kaifu_time HTTP/1.1" 301 0 [15/Jan/2018 15:02:22] "GET /mt/kaifu_time/ HTTP/1.1" 200 19539 mt_ios999game--open in .... mt_ios999game--open in .... <==这里的打印两次 Exception in thread APScheduler: Traceback (most recent call last): File "/usr/local/lib/python2.7/threading.py", line 801, in __bootstrap_inner self.run() File "/usr/local/lib/python2.7/threading.py", line 754, in run self.__target(*self.__args, **self.__kwargs) File "/qzdata1/python_env/LazyOps/lib/python2.7/site-packages/apscheduler/schedulers/blocking.py", line 30, in _main_loop wait_secOnds= self._process_jobs() File "/qzdata1/python_env/LazyOps/lib/python2.7/site-packages/apscheduler/schedulers/base.py", line 981, in _process_jobs self.remove_job(job.id, jobstore_alias) File "/qzdata1/python_env/LazyOps/lib/python2.7/site-packages/apscheduler/schedulers/base.py", line 613, in remove_job raise JobLookupError(job_id) JobLookupError: u'No job by the id of mt_ios999game_in_1516005540000 was found' 

    我把两个 add_job()位置互掉后,即先添加 add_job(func=open_out...) 再添加 add_job(func=open_in..)

    然后 open_out 会被执行两次。

    这样的问题,我应如何修改。

    感觉毫无逻辑出现这问题,一次性任务,会被重复执行,而且是同一时间的。

    7 条回复    2019-12-25 02:47:26 +08:00
    oncew
        1
    oncew  
       2018-07-30 15:46:46 +08:00
    偶然看到这个问题,虽然很久了,但是回复一下可能的原因:你的程序运行的是 debug 模式,或者多进程,多线程模式时候,会有多个 scheduler 实例,这个时候会造成任务多次执行
    fanne
        2
    fanne  
    OP
       2018-07-30 15:58:17 +08:00
    @oncew #1 嗯,很大可能是的,后面遇到一个情况,有个 java 项目,因为某种原因起了两个进程,然后每日日报分析的时候,就多了一倍,然后我想到,我这个问题也有可能是类似问题造成的,不过当时没找到原因,就把这个功能撤了,就没有去测试。

    为了图简便,我的项目程序,直接 python manage.py runserver 丢后台跑
    然后有天我发现,我其实每次重启项目,这个进程都没停止掉就又起了一个,然后发现是有好多个进程的

    所以,很大可能是你描述的这个问题。
    oncew
        3
    oncew  
       2018-09-06 06:45:16 +08:00
    v2ex 的提醒功能做的不好,看其他消息提醒的时候,才注意这个帖子.. 重复执行的原因我能确定是多进程造成的问题,后面看了下 apschedler 的源码,对于多线程的情况是有加锁执行任务的,防止重复执行(希望没记错--),但是多进程的情况,这个线程锁没用,debug 模式(也会多起一个进程监听),后面我尝试加了一个多进程的锁,发现许多坑仍然没有解决,实现的功能也是 celery 已经早就解决的问题,所以我觉得用 celery 是最好的解决方案
    mingxu     4
    mingxu  
       2018-09-11 10:42:03 +08:00
    相比 APScheduler,celery 不能实现动态添加任务的功能吧。这个问题还有其他的解决办法么?
    boyzhh
        5
    boyzhh  
       2019-11-12 04:01:03 +08:00
    我也遇到这个问题了,最简单的提交表格新建记录,经过反复测试,随机性的出现一个 view 同时执行两次,导致报错记录已存在,但因为执行了两次,新的记录也能存入,测试大概是 7-10 次就会出现一次同时执行两次的情况,莫名其妙,关闭了 debug 模式也一样
    fanne
        6
    fanne  
    OP
       2019-11-12 08:50:42 +08:00
    @boyzhh 后面有定位到哪问题么。
    boyzhh
        7
    boyzhh  
       2019-12-25 02:47:26 +08:00
    @fanne 恩,找到问题了,是 APPEND_SLASH=True 这个设置,就是连接结尾如果没有'/'自动加上,中间调试的时候打开这个的,也没注意,后来就间歇性出错,找了一通也没找到原因,后来努力回想改过什么配置,把这个去掉了就好了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1254 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 23:56 PVG 07:56 LAX 15:56 JFK 18:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86