Nginx技术总结之三——Nginx多进程IO模型

接上篇《Nginx技术总结之二——Nginx进程模型》

三. Nginx 的多进程 IO 模型

参考地址:《为啥性能高?Nginx架构初探》

3.1 多进程 IO 模型的优点

首先,对于每个 worker 进程来说,独立的进程不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。
其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快启动新的 worker 进程。当然,worker 进程的异常退出,肯定是程序漏洞导致异常退出,这样会导致当前 worker 上的所有请求失败,不过不会影响到所有请求,所以降低了风险。

3.2 异步非阻塞

Nginx 采用了异步非阻塞的方式来处理请求。也就是说,Nginx 是可以同时处理成千上万个请求的。
一个 worker 进程可以同时处理的请求数只受限于内存大小,而且在架构设计上,不同的 worker 进程之间处理并发请求时几乎没有同步锁的限制,worker 进程通常不会进入睡眠状态,因此,当 Nginx 上的进程数与 CPU 核心数相等时(最好每一个 worker 进程都绑定特定的 CPU 核心),进程间切换的代价是最小的。

而 Apache 的常用工作方式,是每个进程在一个时刻只处理一个请求。因此,当并发数上到几千时,就同时有几千的进程在处理请求了。这对操作系统来说,进程带来的内存占用非常大,进程的上下文切换带来的 CPU 开销很大,性能自然就上不去了,同时这些开销完全是没有意义的。

为什么 Nginx 可以采用异步非阻塞的方式来处理?一个请求的完整过程,首先请求过来要建立连接,然后再接收数据,接收数据后再发送数据。
具体到系统底层,就是读写事件,而当读写事件没有准备好时,必然不可操作。如果不用非阻塞的方式来调用,那就得阻塞调用了。阻塞调用的情况下,事件没有准备好,那就只能等到事件准备好了再继续。阻塞调用会进入内核等待,CPU 就会让出去给别人用了,对单线程的 worker 来说,显然不合适。当网络事件越多时,大家都在等待呢,CPU 空闲下来没人用,利用率自然上不去了,更别谈高并发了。阻塞明显是不适合的,那么考虑非阻塞。
非阻塞就是,事件没有准备好,马上返回 EAGAIN,就是等到时间准备好再进行通知,或者过一会再来检查一下事件,直到事件准备好了为止,在这期间,你就可以先去做其它事情,然后再来看看事件好了没。虽然不阻塞了,但你得不时地过来检查一下事件的状态,你可以做更多的事情了,但带来的开销也是不小的。

3.3 epoll

Epoll 相关内容见《Redis 多路复用篇》 的详解。

你可能感兴趣的:(网络,nginx,Java)