Nginx工作原理和优化.docx
- 文档编号:4344492
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:12
- 大小:78.32KB
Nginx工作原理和优化.docx
《Nginx工作原理和优化.docx》由会员分享,可在线阅读,更多相关《Nginx工作原理和优化.docx(12页珍藏版)》请在冰豆网上搜索。
Nginx工作原理和优化
目录(?
)[-]
1.Nginx的模块与工作原理
2.NginxFastCGI运行原理
1.什么是FastCGI
2.NginxFastCGI运行原理
3.spawn-fcgi与PHP-FPM
4.NginxPHP-FPM
3.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、什么是FastCGI
FastCGI是一个可伸缩地、高速地在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和kill
3.和application(php)进行通信
3、spawn-fcgi与PHP-FPM
FastCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是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-FPM
PHP-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_address 127.0.0.1:
9000#这个表示php的fastcgi进程监听的ip地址以及端口
start_servers
min_spare_servers
max_spare_servers
Nginx配置运行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-select_module和–without-select_module来启用或禁用这个模块。
∙poll –标准方法。
如果当前平台没有更有效的方法,它是编译时默认的方法。
你可以使用配置参数–with-poll_module和–without-poll_module来启用或禁用这个模块。
∙kqueue –高效的方法,使用于FreeBSD4.1+,OpenBSD2.9+,NetBSD2.0和MacOSX.使用双处理器的MacOSX系统使用kqueue可能会造成内核崩溃。
∙epoll –高效的方法,使用于Linux内核2.6版本及以后的系统。
在某些发行版本中,如SuSE8.2,有让2.4版本的内核支持epoll的补丁。
∙rtsig –可执行的实时信号,使用于Linux内核版本2.2.19以后的系统。
默认情况下整个系统中不能出现大于1024个POSIX实时(排队)信号。
这种情况对于高负载的服务器来说是低效的;所以有必要通过调节内核参数/proc/sys/kernel/rtsig-max来增加队列的大小。
可是从Linux内核版本2.6.6-mm2开始,这个参数就不再使用了,并且对于每个进程有一个独立的信号队列,这个队列的大小可以用RLIMIT_SIGPENDING参数调节。
当这个队列过于拥塞,nginx就放弃它并且开始使用poll方法来处理连接直到恢复正常。
∙/dev/poll –高效的方法,使用于Solaris711/99+,HP/UX11.22+(eventport),IRIX6.5.15+和Tru64UNIX5.1A+.
∙eventport –高效的方法,使用于Solaris10.为了防止出现内核崩溃的问题,有必要安装 这个 安全补丁。
在linux下面,只有epoll是高效的方法
下面再来看看epoll到底是如何高效的
Epoll是Linux内核为处理大批量句柄而作了改进的poll。
要使用epoll只需要这三个系统调用:
epoll_create
(2),epoll_ctl
(2),epoll_wait
(2)。
它是在2.5.44内核中被引进的(epoll(4)isanewAPIintroducedinLinuxkernel2.5.44),在2.6内核中得到广泛应用。
epoll的优点
∙支持一个进程打开大数目的socket描述符(FD)
select最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。
对于那些需要支持的上万连接数目的IM服务器来说显然太少了。
这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完美的方案。
不过epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat/proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
∙IO效率不随FD数目增加而线性下降
传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是”活跃”的,但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。
但是epoll不存在这个问题,它只会对”活跃”的socket进行操作—这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。
那么,只有”活跃”的socket才会主动的去调用callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个”伪”AIO,因为这时候推动力在os内核。
在一些benchmark中,如果所有的socket基本上都是活跃的—比如一个高速LAN环境,epoll并不比select/poll有什么效率,相反,如果过多使用epoll_ctl,效率相比还有稍微的下降。
但是一旦使用idleconnections模拟WAN环境,epoll的效率就远在select/poll之上了。
∙使用mmap加速内核与用户空间的消息传递。
这点实际上涉及到epoll的具体实现了。
无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。
而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工mmap这一步的。
∙内核微调
这一点其实不算epoll的优点了,而是整个linux平台的优点。
也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。
比如,内核TCP/IP协议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小—通过echoXXXX>/proc/sys/net/core/hot_list_length完成。
再比如listen函数的第2个参数(TCP完成3次握手的数据包队列长度),也可以根据你平台内存大小动态调整。
更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。
(epoll内容,参考epoll_互动百科)
4. Nginx优化
1. 编译安装过程优化
1).减小Nginx编译后的文件大小
在编译Nginx时,默认以debug模式进行,而在debug模式下会插入很多跟踪和ASSERT之类的信息,编译完成后,一个Nginx要有好几兆字节。
而在编译前取消Nginx的debug模式,编译完成后Nginx只有几百千字节。
因此可以在编译之前,修改相关源码,取消debug模式。
具体方法如下:
在Nginx源码文件被解压后,找到源码目录下的auto/cc/gcc文件,在其中找到如下几行:
1.# debug
2.CFLAGS=”$CFLAGS -g”
注释掉或删掉这两行,即可取消debug模式。
2.为特定的CPU指定CPU类型编译优化
在编译Nginx时,默认的GCC编译参数是“-O”,要优化GCC编译,可以使用以下两个参数:
1.--with-cc-opt='-O3'
2.--with-cpu-opt=CPU #为特定的 CPU 编译,有效的值包括:
pentium, pentiumpro, pentium3, # pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64
要确定CPU类型,可以通过如下命令:
1.[root@localhost home]#cat /proc/cpuinfo | grep "model name"
2.利用TCMalloc优化Nginx的性能
TCMalloc的全称为Thread-CachingMalloc,是谷歌开发的开源工具google-perftools中的一个成员。
与标准的glibc库的Malloc相比,TCMalloc库在内存分配效率和速度上要高很多,这在很大程度上提高了服务器在高并发情况下的性能,从而降低了系统的负载。
下面简单介绍如何为Nginx添加TCMalloc库支持。
要安装TCMalloc库,需要安装libunwind(32位操作系统不需要安装)和google-perftools两个软件包,libunwind库为基于64位CPU和操作系统的程序提供了基本函数调用链和函数调用寄存器功能。
下面介绍利用TCMalloc优化Nginx的具体操作过程。
1).安装libunwind库
可以从http:
//download.savannah.gnu.org/releases/libunwind下载相应的libunwind版本,这里下载的是libunwind-0.99-alpha.tar.gz。
安装过程如下:
1.[root@localhost home]#tar zxvf libunwind-0.99-alpha.tar.gz
2.[root@localhost home]# cd libunwind-0.99-alpha/
3.[root@localhost libunwind-0.99-alpha]#CFLAGS=-fPIC ./configure
4.[root@localhost libunwind-0.99-alpha]#make CFLAGS=-fPIC
5.[root@localhost libunwind-0.99-alpha]#make CFLAGS=-fPIC install
2).安装google-perftools
可以从http:
//google-下载相应的google-perftools版本,这里下载的是google-perftools-1.8.tar.gz。
安装过程如下:
1.[root@localhost home]#tar zxvf google-perftools-1.8.tar.gz
2.[root@localhost home]#cd google-perftools-1.8/
3.[root@localhost google-perftools-1.8]# ./configure
4.[root@localhost google-perftools-1.8]#make && make install
5.[root@localhost google-perftools-1.8]#echo "/usr/
local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
6.[root@localhost google-perftools
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Nginx 工作 原理 优化