zoukankan      html  css  js  c++  java
  • APScheduler可能遇到的问题

    uWsgi使用多进程模式启动Django项目,因此我们会有多个进程去执行这个定时任务,导致定时任务被重复执行。解决这个问题的方法,我们直接就会想到采用加锁的方式。第一个拿到锁的进程,执行定时任务,其余的进程由于拿不到锁,因此也就不会执行定时任务。下面给出两种加锁方案,分别适用于不同的场合。
    

    redis分布式锁

    def testaps():
        cache=get_redis_connection("default")
        key = f"APS_Lock"
        lock = cache.set(key, value=1, nx=True, ex=180)     # 180s之后锁自动消失,因此无需释放锁。
        if lock:
            scheduler = BackgroundScheduler()
            def my_job():
                print (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
            scheduler.add_job(my_job, 'interval', seconds=10)
            scheduler.start()
        else:
            ...
    testaps()   # 执行函数
    当多个进程都执行testaps方法的时候,只有第一个拿到redis锁(这是个原子操作)的进程才能开启定时任务,其他的进程都无法开启定时任务,这样就可以保证定时任务只被执行一次。
    

    文件锁

    import atexit
    import fcntl
     
    def init():
        f = open("scheduler.lock", "wb")
        try:
            fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)   # 加锁
            scheduler = BackgroundScheduler()
            def my_job():
                print (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
            scheduler.add_job(my_job, 'interval', seconds=10)
            scheduler.start()
        except:
            pass
        def unlock():
            fcntl.flock(f, fcntl.LOCK_UN)   
            f.close()
        atexit.register(unlock)     # 释放锁
    # atexit模块定义了清理函数的注册和反注册函数. 被注册的函数会在解释器正常终止时执行
    
    init()  # 执行函数
    

    atexit模块说明

    https://docs.python.org/zh-cn/3/library/atexit.html
    

    -------------------------------------------

    个性签名:代码过万,键盘敲烂!!!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    测试VPS
    [转] 如何在vps上安装和登录Xwindows
    [转]设置修改CentOS系统时区
    顺序队列
    求二叉树的高度
    VMware Workstation cannot connect to the virtual machine
    如何查看hadoop是32位还是64位
    64位CentOS上编译 Hadoop 2.2.0
    hadoop 2.X下eclipse配置
    删除文件及文件夹
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/15770588.html
Copyright © 2011-2022 走看看