内容简介:Nginx采用的模型是master-worker模型,即:将里面核心的流程和函数抽取出来,如下图所示:
master进程
Nginx采用的模型是master-worker模型,即:
- 由master进程负责创建worker进程,以及监控worker进程的情况,如需要更新配置的情况下发消息给worker进程重新加载配置等。
- master进程负责具体网络事件。
将里面核心的流程和函数抽取出来,如下图所示:
- master进程的主循环在函数ngx_master_process_cycle中,主要负责:
- 调用ngx_start_worker_processes函数创建worker子进程。
- 监控各种信号量的变化做处理,比如需要停止进程、重新加载配置等。
- master进程最终会调用函数ngx_spawn_process函数来创建出worker子进程:
- 使用共享内存创建出用于master-worker进程之间通信的channel。
- fork出子进程之后,进入worker进程的主函数ngx_worker_process_cycle。
以下列举出几个相关的信号量:
信号 | 对应全局变量 | 处理 |
---|---|---|
QUIT | ngx_quit | 优雅关闭整个Nginx服务 |
TERM或者INT | ngx_terminate | 强制关闭Nginx服务 |
USR1 | ngx_reopen | 重新打开文件 |
WINCH | ngx_noaccept | 所有worker进程不再接受新的连接,相当于给子进程发送QUIT信号 |
USR2 | ngx_change_binary | 平滑升级到新的Nginx二进制文件 |
HUP | ng_reconfigure | 重新加载配置文件 |
CHLD | ngx_reap | 需要监控所有子进程 |
worker进程
worker进程的函数入口在ngx_worker_process_cycle中,其主要做的工作分为两部分:
- 调用ngx_process_events_and_timers处理IO事件以及定时器事件。
- 判断ngx_terminate、ngx_quit、ngx_reopen这几个变量是否被置位来做相应的处理。
下面主要谈网络IO事件的处理,即ngx_process_events_and_timers函数。
先来介绍几个与接收连接相关的全局变量:
- ngx_use_accept_mutex:由配置项accept_mutex配置,表示是否需要使用accept锁,只有抢到该锁的worker才允许接收新的连接。
- ngx_accept_mutex_delay:由配置项accept_mutex_delay配置,在开启accept_mutex的情况下,一个worker进程在抢不到accept锁的情况下,最长多少时间才重新接收新的连接。
- ngx_accept_disabled:值为ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n,可以看到当链接数量到nginx.conf中配置的worker_connections的7/8以上时,这个变量ngx_accept_disabled为正数,此时不会接收新的连接,直到该值小于等于0为止。
- ngx_accept_mutex_held:表示是否抢到了accept锁,只有抢到的才能接收新连接。
具体来看看ngx_process_events_and_timers函数中与接收连接相关的逻辑,伪代码如下:
如果开启了accept_mutex配置: 如果当前ngx_accept_disabled大于0,表示不能接收新的连接,直接返回。 否则尝试获取accept mutex。 如果获取accept mutex锁成功: 将调用事件轮询函数的标志位加上NGX_POST_EVENTS标志 如果获取失败: 调用事件轮询函数的事件参数不得超过ngx_accept_mutex_delay值。 调用ngx_process_events函数处理轮询事件 调用ngx_event_process_posted(cycle, &ngx_posted_accept_events)函数处理accept事件 如果前面拿到了accept mutex锁,则释放这个锁,好让其他worker也有机会接收新的连接 调用ngx_event_expire_timers处理定时器事件 调用ngx_event_process_posted(cycle, &ngx_posted_events);函数处理除了accept事件以外的其他post事件
在ngx_process_events处理函数中,当传入的flags有NGX_POST_EVENTS标志时,意味着并不马上在这个函数中调用事件的回调函数进行处理,而是放在一个队列中,回头在后面的ngx_event_process_posted函数中再进行处理。
而这里的队列分为两类:
- ngx_posted_accept_events用于存放接收新连接事件。
- ngx_posted_events用于存放除了accept之外的其他事件。
这样的做法,是为了将接收新连接的事件优先级放在其他IO事件以及定时器事件之前。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- JStorm 源码解析:基础线程模型
- Kafka 源码解析:网络交互模型
- Netty源码分析--内存模型(上)(十一)
- Netty源码分析--Reactor模型(二)
- Netty源码分析系列之Reactor线程模型
- 高并发秒杀架构模型设计附源码案例
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。