对于每一个进程都有一个事件缓存,对于worker进程而言,除了nginx启动时更显一次时间外,任何更新时间的操作都只能由ngx_epoll_process_events方法执行。在此方法中,当flags参数中有NGX_UPDATE_TIME标志位,或者ngx_event_timer_alarm标志位为1时,就会调用ngx_time_update方法更新缓存时间。
在配置文件中可以设定更新时间的频率功能,也就是至少每隔timer_resolution毫秒必须更新一次缓存时间。
Ngx_event_core_moudle模块初始化时会使用setitimer系统调用告诉内核每隔timer_resolution毫秒调用一次ngx_timer_signal_handler方法,而ngx_timer_signal_handler方法则会将ngx_event_timer_alarm标志位设为1,这样一来,一旦调用ngx_epoll_process_events方法,如果间隔的时间超过timer_reolution毫秒,肯定会更新缓存时间。
如果很久都不调用ngx_epoll_process_events方法呢?例如,远超过timer_resolution毫秒的时间内ngx_epoll_process_events方法都得不到调用,那时间精度如何保证呢?在这种情况下,Nginx只能从时间模块对ngx_event_actions中process_events接口的实现来保证时间精度了,process_events方法的第二个参数timer表示收集事件时的最长等待时间。例如,在epoll模块下,这个timer就是epoll_wait调用时传入的超时时间参数,如果没有设置timer_resolution,一般清下,process_events方法的timer参数都是大于0小于500毫秒的值,二如果在设置了timer_resolution后,这个timer参数就是-1,它表示如果epoll_wait等调用检测不到已经发生的时间,将不等待而是立刻放回。
定时器是一个红黑树,可以这个任务时间更新:
配置文件中设置了timer_resolutiOn,那么epoll_wait中时间参数就是-1,一定的时间频率更新时间或者有事件来就更新时间;如果没有设置timer_resolution,那么就从定时器的红黑树中挑选一个最新的时间最为epoll_wait中时间的参数。