当前位置:首页 > 热点

linux nginx php

linux nginx php

三年前我接手一个日活两万的社区站,服务器是台四核八G的旧机器。运维说撑不住,要上集群。我看了看监控,CPU峰值才30%,但php-fpm的进程数飙到了280。问题不在硬件,在nginx和php的配合方式。

nginx处理静态文件是天赋,但碰到php就得把请求扔给fastcgi。这里有个几乎没人调的参数——fastcgi_buffers。默认8k,php返回的json动不动就50k,nginx得先攒够缓冲区再吐给浏览器,慢就慢在这。改成fastcgi_buffers 16 16k,响应时间直接砍半。这种事儿网上教程不会写,得自己压测才摸得着。

另一个坑是socket连接。很多人用unix:/tmp/php-cgi.sock,但没注意权限。有次php-fpm换用户跑,nginx报502,查了半天是sock文件属主没改。后来我干脆用tcp:fastcgi_pass 127.0.0.1:9000,省心。性能损失?局域网内几乎无感,但排查问题方便太多。

说到php-fpm,pm.max_children设多少?有个简单公式:可用内存除以单个php进程平均内存。拿ps aux | grep php-fpm看看,通常每个进程吃30-40M。那台8G机器,给php留4G,算下来pm.max_children = 100左右。设太大,内存爆了直接OOM;设太小,高峰期请求排队,nginx那边表现为连接超时。

别忘了pm.start_servers和pm.min_spare_servers。默认值偏保守,动态启动进程要时间,流量突刺时就会看到nginx日志里一堆connect() to unix:/tmp/php-cgi.sock failed。我习惯把start_servers设成max_children的30%,min_spare设成20%,max_spare设成50%。这样进程池能快速响应波动,又不至于空转浪费。

最后说个细节——nginx的keepalive。默认对fastcgi是关闭的,每次请求都重新建立连接。php-fpm支持复用,在nginx配置里加:

 location ~ \.php$ {  fastcgi_pass 127.0.0.1:9000; fastcgi_keep_conn on; } 

就这么一行,长连接下php处理小请求的吞吐能涨15%。别小看这点,日请求百万级时,省下的握手开销很可观。

那台旧机器后来扛了一年半,直到业务涨到五倍才换硬件。中间只调过三次nginx和php配置,每次改动都盯着ab压测数据。Linux下调优不像写业务代码那么直观,但当你看到load average从3.2降到0.8,那种踏实感是实打实的。

分享到: