目录(?)[-]1.Nginx的模块与工作原理2.NginxFastCGI运行原理1.什么是FastCGI2.NginxFastCGI运行原理3.spawn-fcgi与PHP-FPM4.NginxPHP-FPM3.Nginx优化1.编译安装过程优化2.利用TCMalloc优化Nginx的性能3.Nginx内核参数优化4.PHP-FPM的优化1.Nginx的模块与工作原理Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个locationblock(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。Nginx的模块从结构上分为核心模块、基础模块和第三方模块:核心模块:HTTP模块、EVENT模块和MAIL模块基础模块:HTTPAccess模块、HTTPFastCGI模块、HTTPProxy模块和HTTPRewrite模块,第三方模块:HTTPUpstreamRequestHash模块、Notice模块和HTTPAccessKey模块。用户根据自己的需要开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。Nginx的模块从功能上分为如下三类。Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。Proxies(代理类模块)。此类模块是Nginx的HTTPUpstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。图1-1展示了Nginx模块常规的HTTP请求和响应的过程。图1-1展示了Nginx模块常规的HTTP请求和响应的过程。Nginx本身做的工作实际很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此次请求映射到一个locationblock,而此location中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做Nginx真正的劳动工作者。通常一个location中的指令会涉及一个handler模块和多个filter模块(当然,多个location可以复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。Nginx的模块直接被编译进Nginx,因此属于静态编译方式。启动Nginx后,Nginx的模块被自动加载,不像Apache,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。在解析配置文件时,Nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。在工作方式上,Nginx分为单工作进程和多工作进程两种模式。在单工作进程模式下,除主进程外,还有一个工作进程,工作进程是单线程的;在多工作进程模式下,每个工作进程包含多个线程。Nginx默认为单工作进程模式。2.Nginx+FastCGI运行原理1、什么是FastCGIFastCGI是一个可伸缩地、高速地在HTTPserver和动态脚本语言间通信的接口。多数流行的HTTPserver都支持FastCGI,包括Apache、Nginx和lighttpd等。同时,FastCGI也被许多脚本语言支持,其中就有PHP。FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后将结果返回给HTTP服务器。这在处理高并发访问时几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少使用了。FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。2、Nginx+FastCGI运行原理Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket可以是文件socket,也可以是ipsocket)。wrapper:为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接收到请求,然后Fork(派生)出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据(html页面或者图片)发送给客户端。这就是Nginx+FastCGI的整个运作过程,如图1-3所示。所以,我们首先需要一个wrapper,这个wrapper需要完成的工作:1.通过调用fastcgi(库)的函数通过socket和ningx通信(读写socket是fastcgi内部实现的功能,对wrapper是非透明的)2.调度thread,进行fork和kill3.和application(php)进行通信3、spawn-fcgi与PHP-FPMFastCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称为FastCGI引擎。spawn-fcgi与PHP-FPM就是支持PHP的两个FastCGI进程管理器。因此HTTPServer完全解放出来,可以更好地进行响应和并发处理。spawn-fcgi与PHP-FPM的异同:1)spawn-fcgi是HTTP服务器lighttpd的一部分,目前已经独立成为一个项目,一般与lighttpd配合使用来支持PHP。但是ligttpd的spwan-fcgi在高并发访问的时候,会出现内存泄漏甚至自动重启FastCGI的问题。即:PHP脚本处理器当机,这个时候如果用户访问的话,可能就会出现白页(即PHP不能被解析或者出错)。2)Nginx是个轻量级的HTTPserver,必须借助第三方的FastCGI处理器才可以对PHP进行解析,因此其实这样看来nginx是非常灵活的,它可以和任何第三方提供解析的处理器实现连接从而实现对PHP的解析(在nginx.conf中很容易设置)。nginx也可以使用spwan-fcgi(需要一同安装lighttpd,但是需要为nginx避开端口,一些较早的blog有这方面安装的教程),但是由于spawn-fcgi具有上面所述的用户逐渐发现的缺陷,现在慢慢减少用nginx+spawn-fcgi组合了。由于spawn-fcgi的缺陷,现在出现了第三方(目前已经加入到PHPcore中)的PHP的FastCGI处理器PHP-FPM,它和spawn-fcgi比较起来有如下优点:由于它是作为PHP的patch补丁来开发的,安装的时候需要和php源码一起编译,也就是说编译到phpcore中了,因此在性能方面要优秀一些;同时它在处理高并发方面也优于spawn-fcgi,至少不会自动重启fastcgi处理器。因此,推荐使用Nginx+PHP/PHP-FPM这个组合对PHP进行解析。相对Spawn-FCGI,PHP-FPM在CPU和内存方面的控制都更胜一筹,而且前者很容易崩溃,必须用crontab进行监控,而PHP-FPM则没有这种烦恼。FastCGI的主要优点是把动态语言和HTTPServer分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求。4、Nginx+PHP-FPMPHP-FPM是管理FastCGI的一个管理器,它作为PHP的插件存在,在安装PHP要想使用PHP-FPM时在老php的老版本(php5.3.3之前)就需要把PHP-FPM以补丁的形式安装到PHP中,而且PHP要与PHP-FPM版本一致,这是必须的)PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。PHP5.3.3已经集成php-fpm了,不再是第三方的包了。PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以被PHP官方收录了。在./configure的时候带–enable-fpm参数即可开启PHP-FPM。fastcgi已经在php5.3.5的core中了,不必在configure时添加--enable-fastcgi了。老版本如php5.2的需要加此项。当我们安装Nginx和PHP-FPM完后,配置信息:PHP-FPM的默认配置php-fpm.conf:listen_address127.0.0.1:9000#这个表示php的fastcgi进程监听的ip地址以及端口start_serversmin_spare_serversmax_spare_serversNginx配置运行php:编辑nginx.conf加入如下语句:location~\.php${roothtml;fastcgi_pass127.0.0.1:9000;指定了fastcgi进程侦听的端口,nginx就是通过这里与php交互的fastcgi_indexindex.php;includefastcgi_params;fastcgi_paramSCRIPT_FILENAME/usr/local/nginx/html$fastcgi_script_name;}Nginx通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理,而这里的IP地址和端口就是FastCGI进程监听的IP地址和端口。其整体工作流程:1)、FastCGI进程管理器php-fpm自身初始化,启动主进程php-fpm和启动start_servers个CGI子进程。主进程php-fpm主要是管理fastcgi子进程,监听9000端口。fastcgi子进程等待来自WebServer的连接。2)、当客户端请求到达WebServerNginx是时,Nginx通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理,即Nginx通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理。3)FastCGI进程管理器PHP-FPM选择并连接到一个子进程CGI解释器。Webserver将CGI环境变量和标准输入发送到FastCGI子进程。4)、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回WebServer。当FastCGI子进程关闭连接时,请求便告处理完成。5)、FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。3.Nginx的IO模型首先nginx支持的事件模型如下(nginx的wiki):Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。select–标准方法。如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数–with