最近在研究一个守卫进程,其主要工作是启动了一个定时任务,但是由于种种原因,定时任务迟迟没有进去。 索性按图索骥,详细分析了一把定时任务相关代码,遂有此文。 (另外csdn上有篇文字分析的也不错,可相互参考) (注意:这一块在L版本会有重构,即将相关内容整合到oslo_service里去了,由于本人源码是L版,环境代码是K版,会有不符合的地方,请甄别)
定时任务使用
openstack中使用@periodic_task.periodic_task来标注对应的方法是一个定时任务。 使用方法是直接把标注置于方法上即可,分为带周期参数
不带周期参数两种,不带参数默认周期是一分钟
定时任务溯源
怎么样,使用定时任务是不是很简单? 但基于冰山原理,简单的背后有极大的繁杂沉浸在水下,让我们抽丝剥茧,一探究竟。
一般来说,openstack中服务进程启动都是类似下图 使用Service构造出一个对象,然后调用server方法lauch起来。
是的,我没有跑题。 具体进程启动的逻辑我们按下不表,但是聪明如你一定知道进程启动会调用到service的start方法。 在service方法start方法中有这么一段代码需要关注(注:periodic_enable来源于上述create方法) 看最后一句,tg是基类中定义的一个线程组(ThreadGroup),它记录了线程和定时器,这里调用的他的add_dynamic_timer,从名字上看就是添加了一个定时器。
这里需要关注下self.periodic_tasks作为回调方法传入,花开两路各表一枝,基于贪心算法,我们这里先按下不表,回头再看。
我们先进入add_dynamic_timer,可以他使用DynamicLoopingCall声明出一个timer,然后启动这个timer
可见,这里孵化了一个线程,周期性的sleep做到定时调用上文所述的回调方法
(定时任务没有执行的问题,最终把相关文件放置到nova项目的对应目录中, 问题解决) (定时任务的代码分析,后续继续)