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)
...