家喻户晓,Nginx 是当下最风行的 Web 服务器,它具备很强的负载平衡,反向代理,邮件代理以及动态缓存的性能。在提供这些性能的同时,Nginx 的性能也极其优良,能够轻松反对百万、千万级的并发连贯,可能为 Tomcat、Django 等性能不佳的 Web 利用抗住绝大部分内部流量。那么,Nginx 是如何实现高速并发解决呢?这就要从它优良的架构设计来说起。
框架结构
如下图所示,Nginx 联合采纳多过程和 IO 多路复用的构造解决并发客户申请。
Master 过程次要负责信号处理,监控和治理 Worker 过程。Master 过程自身不解决具体业务。Worker 过程解决具体业务,包含解决连贯申请和网络读写事件的解决。多个 worker 过程能够独立地解决各自的客户连贯。Worker 过程之间通过信号量和共享内存进行通信。
通过配置与零碎 CPU 等量的 worker 过程,能够实现某一个过程绑定某一个特定 CPU 从而缩小零碎开销。在每一个 worker 过程解决多个 client 并发连贯申请时,Nginx 采纳 IO 多路复用技术在一个过程内同时解决多个 client 的网络读写事件。与多过程 / 线程解决多连贯申请模型相比,IO 多路复用能够缩小大量的过程调度带来的零碎开销,从而进步零碎整体的解决性能。
并发解决形式
网络服务器在解决并发解决形式,如上图 socket 解决流程所示,依据 accept 失去新连贯当前是启用新的过程 / 线程还是间接在原来本过程内解决,分为如下两种形式。
一种是多过程 / 线程形式,这种形式为每一个新来的连贯生成一个新的过程 / 线程来独自解决。另外一种是 IO 多路复用,这种形式在一个过程 / 线程中保护所有的连贯的 socket, 通过事件处理的形式顺次解决所有连贯上的网络事件。
多线程模型如下:
在多过程 / 线程的模型中,依据 accept 在新老过程中的地位又分为两种。一种类型是 accept 在父过程中进行,每次 accept 当前,fork 一个新过程或者创立一个新线程来解决新 accept 的连贯。一种类型是父过程在 listen 调用当前,fork 出多个过程或者创立多个线程别离进行 accept.
IO 多路复用模型如下:
IO 多路复用又称为 event driven IO。就是在同一个过程内同时解决多路 IO,进而进步零碎吞吐量。个别是通过保护一个连接池,当某个连贯有数据达到,告诉过程来进行数据处理。Nginx 反对多种并发连贯申请,比方 select,poll,epoll,kqueue(针对 bsd) 等等,这些申请能够通过配置文件进行抉择。个别在 linux 上 epoll 的效率要比 select,poll 高很多。
综上所述,Nginx 通过自身优良的框架设计,加上内核对并行网络解决的反对,失去了十分好的并发解决性能。