前言
一个简单的需求,即定时启动 Python 脚本,这种需求很常见,比如定时启动一段程序对服务器状态进行收集,写到文件中,方便运维后期审计,查看服务器占用高峰时间段,从而判断出公司产品在该时间段较多人使用,或定时清除其他程序的日志,释放线上服务器的空间。这块常见的架构是有个转存程序,将日志通过 nginx 文件服务挂起,然后该程序请求这种文件,将其存储在数据服务器中,而线上服务器的日志就不需要了(游戏日志通常比较大,所以转存程序也需要设计一下)。
我们来实现一下定时启动 Python 的需求,当然,定时启动其他任何程序也都一样。
Python threading 模块
一开始,为了省事,直接使用 Python 的 threading 模块。threading 模块下有个 Timer 模块,它可以实现定时启动 Python 程序的需求,用法如下:
from threading import Timer
import datetime
def timedTask():
print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
main() # 主题程序逻辑
global timer
timer = Timer(300, timedTask)
timer.start()
if __name__ == '__main__':
timedTask()
值得一提的是,timer 需要使用 global timer,据说尝试运行时,会释放无需使用的占用资源。
实现方法很简单,即创建 Timer() 实例,传入两个参数,分别是时间间隔(单位为秒)与定时任务本身,构成一个死递归(因为没有逃出条件),然后就是调用 Timer 实例的 start() 方法。
不推荐,虽然网上博客说使用 global timer 会释放无用资源,但实际没有考证,这种写法在服务器上跑起来的程序通常一天就断。我周日启动该程序,周一来公司看,对应的 Python 程序挂了。
APScheduler
APScheduler 是 Python 用于执行定时操作的第三方框架,作为一个框架,它就有它对应的各种概念,没必要搞那么复杂,学习成本有点高,放弃。
Linux crontab
最后还是转到了 Linux 的 crontab 服务,该服务主要就是用于实现定时任务的,其语法如下:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed
minute: 代表一小时内的第几分,范围 0-59。
hour: 代表一天中的第几小时,范围 0-23。
mday: 代表一个月中的第几天,范围 1-31。
month: 代表一年中第几个月,范围 1-12。
wday: 代表星期几,范围 0-7 (0 及 7 都是星期天)。
who: 要使用什么身份执行该指令,当您使用 crontab -e 时,不必加此字段。
command: 所要执行的指令。
crontab 服务状态
service crond start
service crond stop
service crond restart
service crond reload
service crond status


