写在前面

写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑。

也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究。

整个NGINX系列的文章中,我会将我的疑惑用红色标出,希望能遇到前辈在评论中给我解答迷津。

定时器

在介绍定时器之前,先简要说下nginx处理事件的流程和方式。

Worker进程的主要流程:

 static void
ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data){
  for(;;) {
  if(ngx_exiting) {}
  ngx_process_events_and_timers(cycle);
  if (ngx_terminate) {}
  if (ngx_quit) {}
  if (ngx_reopen) {}
} void
ngx_process_events_and_timers(ngx_cycle_t *cycle) {
  (void) ngx_process_events(cycle, timer, flags);
}

ngx_process_events调用epoll(linux下)实现事件的处理。

ngx_process_events处理事件有两种方式:一是直接调用处理函数处理,二是将事件放到post队列中,函数返回后再处理队列中的事件。

在使用了 NGX_POST_EVENTS标记时,ngx_process_events不直接处理事件,将事件放到Post队列中,待函数返回,再在队列中取出事件处理。

因为调用ngx_process_events会加锁(为什么加锁?),函数返回后,将锁释放再处理事件,可以减少锁的占用时间。

以上是nginx处理事件的大体方式,下面介绍nginx中定时器的实现。

Nginx定时器使用红黑树组织(为什么使用红黑树,红黑树效率高到哪?可以研究下)存储,这个不多说。

Nginx定时器的触发有两种方式,第一种是设置时间信号。

ngx_event_process_init函数中 ,设置了时间信号,每隔固定时间触发,时间信号的处理函数,只是设置ngx_event_timer_alarm = 1,但他会中断ngx_process_events中epoll_wait的处理,epoll_wait返回后,调用ngx_time_update更新时间,接着返回到函数ngx_process_events_and_timers中处理,ngx_process_events_and_timers中,会调用ngx_event_expire_timers,查询超时的事件并处理。

但这种方式有个问题,如果事件信号是在处理IO事件时(epoll_wait调用之后)发生的,那么定时器的查询遍历,只能到下一次epoll_wait调用时才会处理,如果这时有IO事件发生,那么epoll_wait可以立即返回,然后因为上次信号发生已经置ngx_event_timer_alarm = 1,可以立即更新时间,ngx_process_events返回后可以处理定时器事件。但如果没有IO事件发生,epoll_wait会阻塞到下次时间信号到来,然后处理定时器事件,这样岂不大大降低了定时器的精确度。这块nginx怎么处理的?

另外每隔固定时间(具体设置的时间信号的时间)才更新时间值,甚至可能是两倍时间信号的时间才更新时间值,那么代码中在插入的定时器,实际触发时间和理论时间就会有这么大的误差。是不是这样呢?

Nginx定时器的第二种触发方式是利用epoll_wait的超时。

每次在调用epoll_wait之前,nginx都会取得下一个最小(最早要触发)的定时器的时间值,然后拿这个值作为epoll_wait的超时时间。这样epoll_wait在返回后就可以处理超时事件了。既可以在频繁IO的情况下处理超时,又可以在IO少量的情况下处理超时。

这种方式epoll_wait返回后,都会先更新时间,这样epoll_wait返回后,在IO事件的处理代码中加入定时器,误差不会太大,因为时间刚刚被更新。

但这个方法的问题是,IO频繁的情况下,也会频繁更新时间,是否会影响性能?

这两种方式各自的优缺点是哪些呢?

NGINX 定时器的更多相关文章

  1. 利用mysqldump 与 nginx定时器 定时备份mysql库

    1.安装mysqldump(如果备份远程mysql库,本地不用安装mysql 也可以单独使用) yum -y install holland-mysqldump.noarch 2.编写备份脚本 首先这 ...

  2. Nginx工作原理

    Nginx的模块 Nginx由内核和模块组成. Nginx的模块从结构上分为核心模块.基础模块和第三方模块: 核心模块:HTTP模块.EVENT模块和MAIL模块 基础模块:HTTP Access模块 ...

  3. 源码编译安装nginx

    安装依赖软件 1.安装编译工具gcc gcc是一个开源编译器集合,用于处理各种各样的语言:C.C++.Java.Ada等,在linux世界中是最通用的编译器,支持大量处理器:x86.AMD64.Pow ...

  4. openresty 定时器

    [1]nginx定时器应用 (1)文件目录结构 (2)nginx.conf配置 lua_package_path "/usr/local/lib/ubcsrvd/lualib/?.lua;; ...

  5. 网络IO超时的几种实现

    一.select/poll/epoll int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,str ...

  6. ngx_lua_API 指令详解(一)ngx.timer.at 指令

    语法: ok,err = ngx.timer.at(delay,callback,user_arg1,user_arg2 ...) 上下文: init_worker_by_lua *,set_by_l ...

  7. 专訪阿里陶辉:大规模分布式系统、高性能server设计经验分享

    http://www.csdn.net/article/2014-06-27/2820432 摘要:先后就职于在国内知名的互联网公司,眼下在阿里云弹性计算部门做架构设计与核心模块代码的编写,主要负责云 ...

  8. [项目] 淘淘商城 Part.1

    电商 市场 2013:79万笔/分钟 2014:13.4万亿,双11支付宝交易峰值285万笔/分钟 2015:50万亿 技术特点 一个Tomcat:500并发 分布式:上万并发 高并发.集群.负载均衡 ...

  9. C++实现红黑树

    红黑树的应用: 利用key_value对,快速查找,O(logn) socket与客户端id之间,形成映射关系(socket, id) 内存分配管理 一整块内存,不断分配小块 每分配一次,就加入到红黑 ...

随机推荐

  1. Python2.7的安装

    >登录python官网下载python2.7的相关版本 python官网链接 >根据平台选择相应的版本 >下载完毕后点击安装即可 >配置环境变量 >安装成功

  2. nginx限制访问速度

    转自:http://siwei.me/blog/posts/nginx-ip 参考:http://tengine.taobao.org/document_cn/http_limit_req_cn.ht ...

  3. App Store有哪些原因会影响app应用上架呢?(分享)

    App Store对于应用上架的审核是非常严格的,很可能一个没有注意到的细节,或者一个你根本没想想到的原因就会导致你的应用上架失败.而排除这些无可避免的错误以外,还有一些导致应用上架失败的原因,非常常 ...

  4. Salesforce select字段的多少对性能影响巨大

    Salesforce select字段的多少对性能影响巨大,第1个是select 144个字段,第2个是select 5个字段, 性能相差了7倍 "select Id,IsDeleted,M ...

  5. php操作Mysql 以及封装常用的函数 用外连接连接3个表的案例

    <?php header("content-type;text/html;charset=utf-8"); //数据库连接define('DB_HOST','localhos ...

  6. YII2.0--------这篇文章记录我学习YII2.0的过程吧,也可以让更多的人少走弯路

    1.情况:今天我从github上下载了一个项目,本以为直接丢到根目录运行就行了,但是不行. 解决办法:首先安装git,安装步骤这里不讲了,稍微讲一下配置环境变量.

  7. 4.用PHP打印出前一天的时间格式是2006-5-10 22:21:21

    echo date('Y-m-d H:i:s', strtotime('-1 days'));

  8. RCNN--对象检测的又一伟大跨越 2(包括SPPnet、Fast RCNN)(持续更新)

    继续上次的学习笔记,在RCNN之后是Fast RCNN,但是在Fast RCNN之前,我们先来看一个叫做SPP-net的网络架构. 一,SPP(空间金字塔池化,Spatial Pyramid Pool ...

  9. Linq To Sqlite 一一二二

    说在前头 之所以写下这些文字,主要是因为使用LINQ的同志们都觉它的美好(至于有多美好,各位心里知道,我就不在描述了,如果你是你还不了解LINQ,园子里有大把的文章),微软老哥只提供了自家的SQLSe ...

  10. Robotium自动化测试框架实用教程(图)

    一.简介 Robotium是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手势操作(点击.长按.滑动等).查找和断言机制的API,能够对各 ...