nginx处理请求的过程简单说明

来源:07素材网 03月27日 17:37
master进程用于管理worker进程,例如接收外界信号、向worker进程发送信号、销毁worker进程、启动worker进程等等。

nginx之所以性能良好,完全是由它的架构决定的。每个worker进程是业务处理进程,负责监听套接字、处理请求、响应请求、代理请求至后端服务器等。

作为web server处理静态资源时每个worker进程的大致流程:

(1).监听套接字。

(2).与客户端建立连接。

(3).处理监听到的连接请求(加载静态文件)。

(4).响应数据。

(5).断开连接。

这几个过程是每个web server都具备的能力,但对于nginx来说,由于它的异步非阻塞,每个过程都不会阻塞(有些小过程必须阻塞的时候还是会阻塞),使得并发处理能力很好。

从监听套接字开始说。每个worker进程都是平等的,它们都可以去监听套接字,正常情况下不可避免地会造成争抢和"惊群问题",而nginx采用"争抢"accept互斥锁的方式,只有持有accept互斥锁的worker进程才有资格将连接请求接到自己的队列中并完成TCP连接的建立。但每个进程是相互独立而平等的,谁有资格去"争抢"互斥锁且有更大几率争抢成功?只要worker进程当前建立的连接数小于worker_connections指令指定的值(实际上源码中设置的是该值的7/8),就允许争抢互斥锁,因为连接数超过了该值的7/8表示已经非常繁忙。除了繁忙程度限制资格,还有epoll_wait的timeout的指标,等待越久的worker进程争抢能力越强。总之,在某一时刻,一定只有一个worker进程监听并accept新的连接请求。

当已经监听到连接请求时,worker进程与它进行三次握手,并最终accpet到自己的内存池中,并和客户端交互数据,处理客户端发送的http请求并响应数据给客户端。但是,nginx的高效就在于它的异步非阻塞,无论是在TCP连接进入ESTABLISHED之前,还是等待客户端发送请求,亦或者是等待加载本地静态资源的I/O,以及响应数据给客户端的任意一个过程中,nginx都是非阻塞的,在任意等待发生时都可以去处理其它事情。当等待的某个资源已经准备成功时将产生事件通知worker进程,worker进程可随后去处理。在此过程中,由于worker进程绑定在一个CPU核心上(推荐如此做),所有的连接都放在内存池中,这使得上下文切换时是极其轻量的,极大地减轻了CPU消耗。从理论上来说,当每个worker绑定了一个CPU核心时,它的并发处理能力主要依赖于内存的大小。

实际上apache httpd的event MPM也是异步非阻塞的,也可以采用epoll,但它采用的是多线程方式,虽然异步,但它的异步似乎不体现在并发能力上,而仅仅只是一些具有特殊状态的连接(如长连接)的异步处理,在处理过程中cpu还是不断地需要在各线程之间大量切换,并发能力并不比worker MPM强多少,相比nginx更是远远不如。
原文出处:https://www.linuxidc.com/Linux/2017-10/147744.htm
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。

头条

在使用SQLite3时遇到的几个坑

在使用SQLite3时遇到的几个坑

《本打算在SQLite3数据库里执行一个查询语句,使用的是php语言,起初遇到的是权限问题: permission denied,因为SQLite3数据库文件和PHP执行者属于两个不同的用户,首先需要对这个文件执行mode 777的权限开放,然后,又遇到了下面这样的PHP错误