浅谈Nginx工作原理

时间:2022-10-27 21:52:07

Nginx

工作原理

    Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,
仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
因此模块可以看做Nginx真正的劳动工作者。通常一个location会涉及一个handler模块和多个filter模块。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。

进程模型

Nginx在启动后,会有一个master进程和多个worker进程。
master进程:主要用来管理worker进程,包含:接收来自外界的信号,
向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。
他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。

FastCGI

    FastCGI是一个可伸缩地、高速地在HTTPserver和动态脚本语言间通信的接口(协议)。多数流行的HTTPserver都支持FastCGI,包括Apache、Nginx和lighttpd等。同时,FastCGI也被许多脚本语言支持,其中就有PHP。
FastCGI的主要优点是把动态语言和HTTPServer分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求。

一般情况下,FastCGI的整个工作流程是这样的:
1、FastCGI进程管理器php-fpm自身初始化,启动主进程php-fpm和启动多个CGI子进程。
主进程php-fpm主要是管理fastcgi子进程,监听9000端口。
fastcgi子进程等待来自Web Server的连接。
2、当客户端请求到达Web Server Nginx时,Nginx通过location指令,
将所有动态请求(以php为后缀的文件)都交给127.0.0.1:9000来处理。
3、FastCGI进程管理器PHP-FPM接收到请求,选择并连接到一个子进程CGI解释器。
Web server将CGI环境变量和标准输入发送到FastCGI子进程。
4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。
当FastCGI子进程关闭连接时,请求便告处理完成。
5、FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。

CGI/FastCGI/PHP-FPM

  • CGI:CGI是Common Gateway Interface(公共网管接口)的缩写,是为了保证web server传递给其他服务器上的程序的数据是标准格式的,方便CGI程序的编写者。
web server(比如说nginx)只是内容的分发者。比如,如果请求index.html,那么nginx会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。
好了,如果请求的是index.php,根据配置文件,nginx知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求简单处理后交给PHP解析器。
Nginx会传哪些数据给PHP解析器呢?url要有吧,查询字符串也得有吧,POST数据也要有,HTTP header不能少吧,好的,CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的一个协议。

当web server收到/index.php这个请求后,会启动对应的CGI程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以CGI规定的格式返回处理后的结果,退出进程。web server再把结果返回给浏览器。
  • FastCGI:FastCGI是用来提高CGI程序性能的。
提高性能,那么CGI程序的性能问题在哪呢?"PHP解析器会解析php.ini文件,初始化执行环境",就是这里了。标准的CGI对每个请求都会执行这些步骤,所以处理每个请求的时间会比较长。那么FastCGI是怎么做的呢?
首先,FastCGI会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。
这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是FastCGI的对进程的管理。
  • PHP-FPM:PHP-FPM是一个实现了FastCGI的程序,被PHP官方收了。
PHP的解释器是php-cgi。php-cgi只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理,所以就出现了一些能够调度php-cgi进程的程序。其中PHP-FPM就是这么个东西,在长时间的发展后,逐渐得到了大家的认可,也越来越流行,在PHP5.3之后纳入PHP内核(之前是一个PHP扩展),使用--enable-fpm这个编译参数即可。