galzk $D php-FPM是一个PHP FastCGI的管理器,它实际上就是PHP源代码的补丁,旨在将FastCGI进程管理引进到PHP软件包中,我们必须将其patch到PHP源代码中,然后再行编译才能使用。而现在我们可以在PHP 5.3.2及更新版本中直接开启并使用即可,因为PHP从该版本已经将其收入到软件包中,所以其不再是补丁包的存在了。
M0yv=g 1J([*) fqjBor} bgLa`8 · 几个概念的理解
]"}BqS0 ]~2iducB, · Nginx+PHP配置
.' }jd# 9U8x&Z]P · Php-Fpm的操作
zOd*> w?>f:2(=[ ?5FlbiT $C.a@gm 一、几个概念的理解
yX4Vv{g ~Oa$rqu%m 1)、CGI
b{qN7X~> \_WR:?l CGI全称“公共网关接口”(Common Gateway Interface),是HTTP服务器与其它机器上的程序进行通信的接口,其程序须运行在网络服务器上。
hw,nA2w\ VcGl8~#9 G &xtL "]#Ij6ml NOTE:
T:u>7?8o yAfwQ$Ll7 CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。
pd:7K'yaw GA[Ebzi .6P.r} W?5') 2)、FastCGI
(/uAn2 k?Z:=.YW FastCGI是一个常驻型的CGI,它可以一直执行,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute模式)。它还支持分布式的运算,即 FastCGI 程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。
5>I-? Ki qFD ZD)K FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。我们知道,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保存在内存中并接受FastCGI进程管理器调度,那么就可以提供良好的性能、伸缩性等。
d
#1Y^3n l::q
F 0 J-hJqR*;K >E>yA d 优点:
|tGUx*NN P9/ (f$ = 1. FastCGI具有语言无关性;
fZ$b8 9B!Sv/)y!r 2. FastCGI独立于核心web服务器运行,提供了一个比API更安全的环境。APIs把应用程序的代码与核心的web服务器链接在一起,这意味着在一个错误的API的应用程序可能会损坏其他应用程序或核心服务器。而恶意的API的应用程序代码甚至可以窃取另一个应用程序或核心服务器的密钥;
Kcm+%p^ S MWXP 3. FastCGI技术目前支持语言有:C/C++、Java、Perl、Tcl、Python、SmallTalk、Ruby等。相关模块在Apache, ISS, Lighttpd等流行的服务器上也是可用的;
{V6&((E8 p?i.<Z 4. FastCGI不依赖于任何Web服务器的内部架构,因此即使服务器技术的变化, FastCGI依然稳定不变;
GGp.u@\r Zz0bd473k? 9MMCWMV .xN<<+|_v' 缺点:
i"h\*B= 4j={ 9e< 因为是多进程,所以比CGI多线程消耗更多的服务器内存,PHP-CGI解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。
x4WCAqi/2 eFG/!b<17 Nginx 0.8.46+PHP 5.2.14(FastCGI)服务器在3万并发连接下,开启的10个Nginx进程消耗150M内存(15M*10=150M),开启的64个php-cgi进程消耗1280M内存(20M*64=1280M),加上系统自身消耗的内存,总共消耗不到2GB内存。如果服务器内存较小,完全可以只开启25个php-cgi进程,这样php-cgi消耗的总内存数才500M。
{7o3wxsS .nPOjwEx&Y 上面的数据摘自Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)。
Lc{AB!Br 32wtN8kx -c_l
n K ?2]fE[SqY 原理:
QP(0 M+ +Dk7B 1. Web服务器启动时,载入FastCGI进程管理器;
\u,CixV= sY;h~a0n 2. FastCGI进程管理器初始化,启动多个CGI解释器进程(PHP-CGI)并等待来自Web服务器的连接;
Ui'v'
$ o%_-u
+ 3. 当客户端请求到达Web服务器时,FastCGI进程管理器选择并连接到一个CGI解释器,Web服务器将CGI环境变量和标准输入发送到FastCGI子进程PHP-CGI。
V'kBF2} cfTT7O#Dc 4. FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回给Web服务器。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web服务器中)的下一个连接。而在CGI模式中,PHP-CGI在此便退出了。
i]ZGq7YJ% evyjHc Cx So ziFI %r^tZ ;;l 在上述情况中,可以想象CGI通常有多慢,每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展,并重初始化全部数据结构。而使用FastCGI,所有这些都只在进程启动时发生一次。另外,数据库持久连接可以工作。
G#%Sokkb' <Y`(J# -5*OSA:8x 1K/HVj+'. NOTE:
:Racu;xf ~>@~U] FastCGI的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求。
[[[C`H@ 7&id(&y/ N^QxqQ~
l;q]z 3)、PHP-CGI
1tY+0R :Quep-:fy< PHP-CGI是PHP自带的FastCGI管理器。
|M?s[}ll {`):X _$T PHP-CGI的不足:
XVNJK-B :?UcD_F 1. php-cgi变更php.ini配置后需重启php-cgi才能让新的php-ini生效,不可以平滑重启。
|cd"cx+ >K'dgJ245 2. 直接杀死php-cgi进程,php就不能运行了(PHP-FPM和spawn-FCGI就没有这个问题,守护进程会平滑重新生成新的子进程)。
S0StC$$1 6Gg`ExcT5 COsy.$|4 </'n={+q 4)、spawn-FCGI
J#Q>dC7 RL&0?OT spawn-FCGI是一个通用的FastCGI管理服务器,它是lighttpd中的一部份,很多人都用Lighttpd的spawn-FCGI进行FastCGI模式下的管理工作,不过有不少缺点。而PHP-FPM的出现多少缓解了一些问题,但PHP-FPM有个缺点就是要重新编译,这对于一些已经运行的环境可能有不小的风险(refer),在php 5.3.3可以直接使用PHP-FPM了。
_#H d2h k5>UAea_ '__>M>[ >!qtue7B spawn-FCGI目前已经独成为一个项目,更加稳定一些,也给很多Web 站点的配置带来便利。已经有不少站点将它与nginx搭配来解决动态网页。最新的lighttpd也没有包含这一块了(http://www.lighttpd.NET/search?q=spawn-FCGI),但可以在以前版本中找到它。在lighttpd-1.4.15
Syseiw /t`|3Mw 版本中就包含了(http://www.lighttpd.net/download/lighttpd-1.4.15.tar.gz),目前spawn-FCGI的下载地址是
http://redmine.lighttpd.Net/projects/spawn-fcgi,最新版本是
http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz。
X9PbU1o; r]-n, <V)z{uK {k=3OIp NOTE:
f6J]=9jU tBkgn3w 最新的spawn-FCGI可以到lighttpd.net网站搜索“spawn-FCGI”找到它的最新版本发布地址。
/JRZ?/<1 ysi=}+F. .Y2Hd$rs $Tv~ *|a 5)、对比spawn-FCGI
l?IeZisX OLt0Q.{ PHP-FPM的使用非常方便,配置都是在PHP-FPM.ini的文件内,而启动、重启都可以从php/sbin/PHP-FPM中进行。更方便的是修改php.ini后可以直接使用PHP-FPM reload进行加载,无需杀掉进程就可以完成php.ini的修改加载
-rYb{<;ST Z # 结果显示使用PHP-FPM可以使php有不小的性能提升。PHP-FPM控制的进程cpu回收的速度比较慢,内存分配的很均匀。
D^>d<LX b3_P??yp spawn-FCGI控制的进程CPU下降的很快,而内存分配的比较不均匀。有很多进程似乎未分配到,而另外一些却占用很高。可能是由于进程任务分配的不均匀导致的。而这也导致了总体响应速度的下降。而PHP-FPM合理的分配,导致总体响应的提到以及任务的平均。
.|u`s,\ E@otV6Wk[@ 4~A$u^scn )c*xKij 二、Nginx+PHP配置
hC8WRxEGq q9_AL8_ 1、进程数优化
yKrbGK*=_ )N~ p4kp pm = dynamic
#>KiX84 >WZbbd- pm.max_children = 300
fQ1j@{Xa !^y;|9?O pm.start_servers = 20
d])ctxB g i/k#3_m pm.min_spare_servers = 5
H;_Ce'oU( z]hRc8g}d pm.max_spare_servers = 35
h4KMhr gQSVPbzK QGOkB h]~FYY 2、最大请求数优化
Hicd
-' f^QC4hf0 pm.max_requests = 10240
am3JzH =AzkE] ,0AS&xs$ 2uT6M%OC NOTE:
YwY?tOxBe Z-ci[Zv 这个用来处理因为PHP解析器或引用的第三方库时,造成的内存泄露问题。
OSUiS`k saZK+kD4I 最大请求数:指一个php-fpm的工作进程在处理多少个请求后就终止掉。
Ca?w"m~h +?3RC$jyw 6A5.n?B{ bxxLAWQ( 3、最长执行时间优化(php.ini)
5"3`ss<m YZOwr72VL request_terminate_timeout = 20
}D)eS |B AIQ
{^: xo @|;Z>&F af6<w.i NOTE:
3K~^H1l b|x B< 这个是用来处理因为PHP执行时间超长而报502错误的解决。
$X.F=Kv |SMigSu r` 这个时长配置可以在php.ini(max_execution_time)或php-fpm.conf中配置均可,为了不影响全局配置,可在php-fpm.conf中实现。
d72
yu3 !}U3{L- 值得注意的是:需要结合nginx.conf中的max_fail(调大些)和fail_timeout(调小些)一同配置。
og+Vrd ^_G#JJ\@$ Ux"
^3D ~PF,[$?4n nginx.conf:
^56D)A= MGwXZ7?E location ~ \.php$ {
*Y53bZ q(s0dkrj …
~^Ga?Q_ &V&beq4)p fastcgi_connect_timeout 180;
~k
6V?z} "Gqas bX fastcgi_read_timeout 600;
7X$pgNRx/a (]fbCH: fastcgi_send_timeout 600;
8193d%Wb \!>qtFT …
!]7L9TGn "x_G6JE4tv }
6(A"5B=\ q8e] {sT'! dt<P6pK- E%Ysyk NOTE:
v]q"{c/ &" yoJ<L PHP-FPM设置的脚本最大执行时间已经够长了,但执行耗时PHP脚本时,发现Nginx报错变为504错误。这是因为我们修改的只是PHP的配置,Nginx中也有关于与上游服务器通信超时时间的配置factcgi_connect/read/send_timeout。
v)zxQuH]^ KC<K*UHPAH 1)-VlQK p ub4(g~E 4、php-fpm高cpu使用排查
~>%% kQt yyVE%e5nl top命令 :
,nniSG((3 /EZ - 直接执行top命令后,输入1就可以看到各个核心的CPU使用率:
Nqj5, 9*c J@q!N;eh| # *7ImEN ]vCs9* |B gYw=Z_z )},/=#C0 sar命令:
)EsFy6K: ,Mn?h\ sar和iostat命令的安装:
RWGAxq`9f P#2#i]- sysstat.x86_64 : The sar and iostat systemmonitoring commands
T FK#ign t)l^$j!h@ yum install -y sysstat.x86_64
YD;"_yH e[.JS6 执行:
]7%+SH,RdD k=.pcDX $sar -P ALL 1 100
2,'%G\QT