tornado实现异步计划任务及python常见计划任务方法

简介:

主要是要实现tornado实现计划任务类crontab间隔 ~


大家看了标题,可能知道我要写啥了 ~ 对头,我用tornado实现一个类似crontab时间间隔调度的程序。

我为啥要写这个?

一方面是 更加深入的了解tornado异步方面的能力 。 另一方面是 在特殊的环境下编写更适合更方便自己的工具。

啥特殊的环境?

比如,我们有好几个后端脚本,这些脚本都要间隔的运行调度。然而这些程序都是秒级别的,这样的话,你用crontab就不太适合了。当然你可以后台仍个脚本,然后sleep 也是可以的。 要是很多的话? 你运行多个脚本?

我上个监控校验项目——就有很多的后台有间隔的脚本跑着。每次系统有改变我都要kill掉进程,调试好了,再start,挺蛋疼的~


后来我把很多的监控校验都放到一个脚本里面,然后开多线程,让他自己去sleep。以后我只需要kill掉一个进程就行了。

Python本身自带了一个调度模块sched,timer,官方给出的例子,都是那样,调用一次的用法。

任务是并发执行的,但是s.run()会把线程堵塞掉,所以咱们有必要把s.run()放到一个独立的线程去运行。当然你要是有需要的话。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>>  import  sched, time
>>> s = sched.scheduler(time.time, time.sleep)
>>> def print_time(): print  "From print_time" , time.time()
...
>>> def print_some_times():
...     print time.time()
...     s.enter( 5 1 , print_time, ())
...     s.enter( 10 1 , print_time, ())
...     s.run()
...     print time.time()
...
>>> print_some_times()
930343690.257
From print_time  930343695.274
From print_time  930343700.273
930343700.276


scheduler实例含有以下方法和属性:

1
2
3
4
5
6
7
8
9
10
11
12
scheduler.enterabs(time, priority, action, argument)
     调度一个新事件,time参数应该是数值类型的。
scheduler.enter(delay, priority, action, argument)
     延迟调度一个事件,不同于相对时间
scheduler.cancel(event)
     在事件队列中移除一个事件,如果事件不在事件队列中,则触发ValueError
scheduler.empty()
   如果事件队列为空则返回True
scheduler.run()
     运行所有的调度事件,该函数会等待下一个事件,然后执行他直到没有可调度的事件为止。
scheduler.queue
   只读属性,返回一个list,里面包含了即将运行的事件列表。


需要关注的是 sched模块不是循环的,一次调度被执行后就完事了,如果想再执行,请再次enter事件了。


我们再来感受下sched里面的timer !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>>  import  time
>>> from threading  import  Timer
>>> def print_time():
...     print  "From print_time" , time.time()
...
>>> def print_some_times():
...     print time.time()
...     Timer( 5 , print_time, ()).start()
...     Timer( 10 , print_time, ()).start()
...     time.sleep( 11 )  # sleep  while  time-delay events execute
...     print time.time()
...
>>> print_some_times()
930343690.257
From print_time  930343695.274
From print_time  930343700.273
930343701.301


说完了后,我们这里跑个实际中能用到的例子:

020053355.jpg


我们跑看看,我们中间加了sleep 2s ,然而他所用的时间是7s,说明他是并发执行的。


020343236.jpg

关于线程的timer我简单写了个例子,跑了下,感觉怪怪的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  threading
import  time
def timer_start():
     t = threading.Timer( 2 ,func,( "xiaorui.cc" , "2s" ))
     t.start()
     t2 = threading.Timer( 4 ,rui,( "4s" , "nima" ))
     t2.start()
def func(msg1,msg2):
     print  "come on," ,msg1,msg2
     print time.strftime( '%Y%m%d%H%M %S' )
     timer_start()
def rui(msg3,nima):
     print  'this is rui %s %s' %(msg3,nima)
     timer_start()
if  __name__ ==  "__main__" :
     timer_start()
     while  True:
         time.sleep( 1 )


运行的结果,时不时的会乱,这东西不太适合做crontab的效果。

我这里微微的总结下:

按照我的测试,sched和timer不适合做循环的计划任务,当然你可以在sched调用函数的时候,用while sleep的方法实现也是靠谱的。。。。

这是脚本的逻辑,大家可以试试

100146806.jpg



感觉python应该有靠谱点的计划任务模块,问了下朋友,他们现在用的是 APScheduler

一个很牛逼的库~ 已经测试过了

特定时间的运行:

1
2
3
4
5
6
7
8
from apscheduler.scheduler  import  Scheduler
sched = Scheduler()
sched.daemonic = False
def job_function(text):
     print text
from datetime  import  datetime
job = sched.add_date_job(job_function, datetime( 2013 10 11 02 36 00 ), [ 'Hello World' ])
sched.start()


间隔的运行:

1
2
3
4
5
6
7
8
9
from apscheduler.scheduler  import  Scheduler
import  time
sched = Scheduler()
sched.daemonic = False
def job_function():
     print  "wan si ni"
     print time.strftime( '%Y%m%d%H%M %S' )
sched.add_interval_job(job_function,  seconds= 3 )
sched.start()

循环3s,ok !!!

024845422.jpg


哈,我简单说了下 python下实现计划任务的几种方式,本来要聊tornado,结果搞到标准库了。

晕,赶紧说正题:

python的web框架中tornado是强大的,他的IOLoop类是Tornado的边缘触发事件驱动模型,在Linux平台下面封装的是epoll模型。这就是他的异步模式的基础。


要是合成到tornado的ioloop的话,我启动一个主程序,不仅把相应的脚本按照间隔调度跑起来,主web也可以访问啦。


用python实现计划任务,除了python自带的shed,timer之外,我能想到的就是开多线程,自己去处理每个任务以及时间间隔。还有就是tornado的ioloop。


精力有限,现在还没有做出像linux系统下的crontab那样的工具。

我想到的思路是 配置文件可以就是crontab的时间语法,或者是咱们用yaml,configparser。程序启动的时候,开一个线程,专门关注这些个数据,对于任务和时间都要采用全局的变量,这些个函数进入主体的时候,先把global变量加载进来,然后大家就懂啦。。。。

下面是我用tornado ioloop实现的方法:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from tornado  import  web, ioloop
import  datetime
period =  5  1000    # every  5  s
class  MainHandler(web.RequestHandler):
     def  get (self):
         self.write( 'Hello Tornado' )
def like_cron():
     print datetime.datetime.now()
def xiaorui():
     print  'xiaorui 2s'
def lee():
     print  'lee 3s'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
if  __name__ ==  '__main__' :
     application = web.Application([
         (r '/' , MainHandler),
         ])
     application.listen( 8081 )
     ioloop.PeriodicCallback(like_cron, period).start()  # start scheduler
     ioloop.PeriodicCallback(lee,  3000 ).start()  # start scheduler
     ioloop.IOLoop.instance().start()


结果:

100352277.png

再跑计划任务的时候,不影响web的访问

100453397.png



一眨眼,发现自己原本要写tornado,结果成大杂烩了~

微微总结下这几种计划任务的方法:

sched 就原版的例子来说,不适合做循环执行的,就单个计划任务是挺不错的。要是想做循环,不要让那个线程死掉,一直while True: 就行了

timer 同sched,不知道为啥多任务的时候,出现奇怪的问题。。。

apscheduler 这个是利器,好用,也是必须推荐使用的。

tornado 我自己觉得是很不错的,他和别的方法不一样,别人是线程,他是异步回调的方式,他背靠着epoll异步,所以很爽。

自己写 这个实现的思路,其实和sched timer,差不多的,我也有提过,就是个多线程,然后while True。





 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1307126,如需转载请自行联系原作者




相关文章
|
1月前
|
机器学习/深度学习 Python
堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能
本文深入探讨了堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能。文章详细介绍了堆叠的实现步骤,包括数据准备、基础模型训练、新训练集构建及元学习器训练,并讨论了其优缺点。
57 3
|
2月前
|
测试技术 API Python
【10月更文挑战第1天】python知识点100篇系列(13)-几种方法让你的电脑一直在工作
【10月更文挑战第1天】 本文介绍了如何通过Python自动操作鼠标或键盘使电脑保持活跃状态,避免自动息屏。提供了三种方法:1) 使用PyAutoGUI,通过安装pip工具并执行`pip install pyautogui`安装,利用`moveRel()`方法定时移动鼠标;2) 使用Pymouse,通过`pip install pyuserinput`安装,采用`move()`方法移动鼠标绝对位置;3) 使用PyKeyboard,同样需安装pyuserinput,模拟键盘操作。文中推荐使用PyAutoGUI,因其功能丰富且文档详尽。
|
21天前
|
安全
Python-打印99乘法表的两种方法
本文详细介绍了两种实现99乘法表的方法:使用`while`循环和`for`循环。每种方法都包括了步骤解析、代码演示及优缺点分析。文章旨在帮助编程初学者理解和掌握循环结构的应用,内容通俗易懂,适合编程新手阅读。博主表示欢迎读者反馈,共同进步。
|
28天前
|
JSON 安全 API
Python调用API接口的方法
Python调用API接口的方法
148 5
|
1月前
|
算法 决策智能 Python
Python中解决TSP的方法
旅行商问题(TSP)是寻找最短路径,使旅行商能访问每个城市一次并返回起点的经典优化问题。本文介绍使用Python的`ortools`库解决TSP的方法,通过定义城市间的距离矩阵,调用库函数计算最优路径,并打印结果。此方法适用于小规模问题,对于大规模或特定需求,需深入了解算法原理及定制策略。
43 15
|
27天前
|
数据采集 JSON 测试技术
Grequests,非常 Nice 的 Python 异步 HTTP 请求神器
在Python开发中,处理HTTP请求至关重要。`grequests`库基于`requests`,支持异步请求,通过`gevent`实现并发,提高性能。本文介绍了`grequests`的安装、基本与高级功能,如GET/POST请求、并发控制等,并探讨其在实际项目中的应用。
37 3
WK
|
1月前
|
Python
Python中format_map()方法
在Python中,`format_map()`方法用于使用字典格式化字符串。它接受一个字典作为参数,用字典中的键值对替换字符串中的占位符。此方法适用于从字典动态获取值的场景,尤其在处理大量替换值时更为清晰和方便。
WK
93 36
|
1月前
|
API 开发者 Python
探索Python中的异步编程:Asyncio与Tornado的对决
在这个快节奏的世界里,Python开发者面临着一个挑战:如何让代码跑得更快?本文将带你走进Python异步编程的两大阵营——Asyncio和Tornado,探讨它们如何帮助我们提升性能,以及在实际应用中如何选择。我们将通过一场虚拟的“对决”,比较这两个框架的性能和易用性,让你在异步编程的战场上做出明智的选择。
|
1月前
|
机器学习/深度学习 人工智能 算法
强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用
本文探讨了强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用,通过案例分析展示了其潜力,并讨论了面临的挑战及未来发展趋势。强化学习正为游戏AI带来新的可能性。
107 4
|
1月前
|
Python
Python编程中的魔法方法(Magic Methods)
【10月更文挑战第40天】在Python的世界中,魔法方法就像是隐藏在代码背后的神秘力量。它们通常以双下划线开头和结尾,比如 `__init__` 或 `__str__`。这些方法定义了对象的行为,当特定操作发生时自动调用。本文将揭开这些魔法方法的面纱,通过实际例子展示如何利用它们来增强你的类功能。
22 1