nginx学习笔记六(Nginx事件框架处理流程)

之前粗略阅读过《Unix网络编程》,这本教材里面是基于底层的Socket  API实现了一些多进程/多线程模式简单的tcp server。Nginx在linux环境下的底层实现肯定也是基于这些基本的socket API做的,但是这些socket API函数都藏在代码的海洋里,需要花些功夫才能将思路给理清楚。接下来整理整理nginx源码中的这些socket API被调用的位置,并且对相应Nginx的事件框架处理流程做一下梳理。

一.最基本的TCP server的程序结构

最基本的TCP server的程序流程如下:

socket ()---->bind()---->listen()----->进入一个无限的循环

在循环中重复:accept()------->recv/write()。

二.Nginx中对应的函数入口

socket() bind() listen() -----------》 ngx_open_listening_sockets()------------》ngx_init_cycle()----------->main.c
如上所示,nginx在启动之后(创建子进程之前)会解析配置文件,把它需要监听的端口加入listening数组。然后针对配置文件中表明需要监听的每个端口做好bind listen这些初始化操作。

worker进程----------->ngx_event_process_init()----------> ngx_add_event()  这些函数是在初始化的时候将监听事件的fd句柄在epoll中进行注册,并且注册其handler(如果不加accept_mutex互斥锁)

worker进程------------>ngx_process_events_and_timers()---------->ngx_trylock_accept_mutex(cycle)----------》ngx_add_event 如果 加了accept_mutex互斥锁,那么只有在进程抢到互斥锁之后才会加监听事件的句柄在epoll中进行注册

worker进程------------>ngx_process_events_and_timers()---------->ngx_process_events()
使用epoll作为事件驱动时候,ngx_process_events也就对应着ngx_epoll_process_events,这里面会调用epoll-wait来取得已经注册好的并且有数据的事件。然后会调用该事件自身的handler来处理或者加入post队列暂缓处理。读事件的handler--ngx_event_accept中会最终调用 accept()系统函数来接受请求。

三.Nginx的事件驱动的特性

1.解决“惊群问题”
本书的作者(阿里陶辉)给出的分析解释很漂亮,可以参见博客:http://blog.csdn.net/russell_tao/article/details/7204260
简单地说,抢互斥锁失败的代价要小于被epoll_wait唤醒但是却抢不到accept代价。所以使用进程互斥锁技术来解决“惊群问题”


2.负载均衡
nginx采用的负载均衡策略很简单,就是每个进程都维护一个ngx_accept_disabled变量,用来表示当前进程处理的连接数目是否超过阈值。如果超过阈值,那么当前进程就不会再去接受新连接。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值