flask flask_apscheduler定时任务

在使用flask_apscheduler定时任务时,可能你会发现项目启动后会重复执行定时任务。在一下2种情况下回出现这种情况:
一、配置完定时任务后启动flask项目时
解决办法:
启动项目前将use_reloader的值设置成False

二、将项目上线Linux服务器时
添加文件锁,由于在Linux中以uwsgi启动,会启动多个进程,如果不加文件锁,启动项目后每个进程都会执行一次定时任务,具体参考下方flask初始化方法

"""task.py"""

def test01():
    print('test01')

def sslMon(domain):
    try:
        hostname = domain
        port = 443
        conn = ssl.create_connection((hostname, port))
        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
        sock = context.wrap_socket(conn, server_hostname=hostname)
        cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
        x509 = OpenSSL.crypto.load_certificate(
            OpenSSL.crypto.FILETYPE_PEM, cert)
        start_date = str(x509.get_notBefore(), encoding='utf-8')
        expire_date = str(x509.get_notAfter(), encoding='utf-8')
        # time 字符串转时间数组
        start_date = datetime.strptime(start_date, "%Y%m%d%H%M%SZ")
        # datetime 字符串转时间数组
        expire_date = datetime.strptime(expire_date, "%Y%m%d%H%M%SZ")
        # 剩余天数
        remain_days = (expire_date-datetime.now()).days
        print('{} ssl start_date,expire_date,remain_days is {},{},{}'.format(
            domain, start_date, expire_date, remain_days))
        return start_date, expire_date, remain_days
    except Exception as e:
        print('{} {}'.format(e.__traceback__.tb_lineno, e))
        return datetime.now(), datetime.now(), -999999999

"""JOBS配置"""

from ..schedule.task import test01,sslMon
class Config(object):
    JOBS = [
        {
            'id': 'test01',
            'func': test01,
            # 'trigger': 'cron',  # 指定任务触发器 cron
            'trigger': 'interval',
            # 'day_of_week': 'mon-fri',  # 每周1至周5早上6点执行
            # 'hour': 6,
            # 'minute': 00
            'seconds': 5,
            'replace_existing': True
        },
        {
            'id': 'sslMon',
            'func': sslMon,
            'args': ['www.baidu.com'],
            'trigger': 'cron',  # 指定任务触发器 cron
            # 'trigger': 'interval',
            'day_of_week': '0-6',  # 每天早上3点半执行
            'hour': 3,
            'minute': 30,
            'second': 0,
            'replace_existing': True
        }
    ]
    SCHEDULER_API_ENABLED = True

"""flask初始化方法"""

import fcntl,atexit
def init_app(config_name):
    ...
     # 定时任务初始化
    f = open('./scheduler.lock', 'wb')
    try:
        #添加文件锁,由于在Linux中以uwsgi启动,会启动多个进程,如果不加文件锁,启动项目后每个进程都会执行一次定时任务
        fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
        scheduler = APScheduler()
        scheduler.init_app(app)
        scheduler.start()
    except Exception as e:
        logging.error(e)

    def unlock():
        fcntl.flock(f, fcntl.LOCK_UN)
        f.close()

    atexit.register(unlock)
    ...
posted @ 2022-05-11 15:21  啦啦la  阅读(1994)  评论(0编辑  收藏  举报