最近和 Nginx 杠上了( 二 )


另外 , 由于Work会在磁盘上进行写入操作 , 为了避免磁盘I/O上的阻塞请求 , 特别是磁盘满的情况 。
可以设置机制和配置文件指令来减轻此类磁盘I/O阻塞情况的发生 。 例如使用sendfile和AIO组合选项提升磁盘性能 。
Nginx进程定义
从架构介绍我们知道Nginx是由不同的进程组成的 , 这些进程各司其职用来处理高并发下的网络请求 , 接下来就看看他们的定义和如何工作的 。
上面介绍了Nginx的总体架构 , 其中重点提到了Master进程和Worker进程 , 其实还有另外两个进程在架构中也起到了重要的作用 。
最近和 Nginx 杠上了
文章图片
图2:Nginx的四类进程
这里我们一起通过图2来认识他们:
Master进程:它作为父进程会在Nginx初始化的时候生成并启动 , 其他的进程都是它子进程 , Master进程对其他进行进行创建和管理 。 Worker进程:是Master的子进程负责处理网络请求 。 这里需要说明一下Nginx为什么采用了多进程而不是多线程的结构 , 其原因是为了保证高可用性 , 进程不像线程那样共享地址空间 , 也避免了当一个线程中的第三方模块出错引而影响其他其他线程的情况发生 。 CacheManager和CacheLoader进程:CacheLoader负责缓存载入 , CacheManager负责缓存管理 , 每一个请求所使用的缓存还是由Worker来决定的 , 而进程间通信都是通过共享内存来实现的 。从上图大家一定注意到了只有Worker进程是多个 , 这是因为Nginx采用了事件驱动的模型 。
为了提高处理请求的效率每个Worker进程会找那个一个CPU内核 , 提高CPU的缓存命中率 , 将某个Worker进程与一个CPU核绑定在一起 。
需要说明的是 , 我们需要根据具体的应用场景来定义Worker进程的数量:
CPU密集型请求 , 例如 , 处理大量TCP/IP , 执行SSL或压缩 , 需要Worker数与CPU内核数量相匹配 。 IO密集型请求 , Worker数需要是CPU内核数量的一到两倍 。上面提到了Master通过控制多个Worker进程来处理网络请求 , 对于Worker的独立进程来说使用资源的时候不需要考虑不需要加锁的问题 , 节省了因为加锁带来的系统开销 。 同时多进程的设计让进程之间不会互相影响 。
当一个进程退出后 , 其它进程还在工作 , Nginx所提供的网络请求服务不会因为其中一个进程的退出而中断 , Master进程一旦发现有Worker进程退出会启动新的Worker进程 。
这里我们会发现Master进程为了控制Worker需要对其进行通信 , 同时Worker进程也需要与Master进程交换信息 。
Nginx启动过程
谈到了Master进程如此的重要 , 那么一起来看看Nginx进程的启动过程 。
最近和 Nginx 杠上了
文章图片
图3:Nginx启动Master进程
如图3所示 , 在Nginx启动的时候会根据配置文件进行解析和初始化的工作 , 同时会从主进程中fork出一个Master进程作为自己的子进程 , 也就是启动Master进程 , 此时Master进程就诞生了 。
Nginx的主进程在fork出Master进程以后就退出了 。 然后Master进程会fork并启动Worker进程 , 以及CacheManager、CacheLoader进程 , 接着Master进程会进入主循环 。
需要注意的是 , 这里使用的fork会复制一个和当前启动进程具有相同代码段、数据段、堆和栈、fd等信息的子进程 。
也就是说我们说的四类进程都是通过Nginx启动进程复制出来的子进程 。
Master启动过程
接着上面的流程Master进程被fork之后 , 会执行ngx_master_process_cycle函数 。
最近和 Nginx 杠上了
文章图片
图4:Master进程执行ngx_master_process_cycle函数