我在一个相当繁忙的互联网站点工作,这个站点通常会遇到非常大的stream量高峰。 在这些峰值期间,每秒钟会有数百页的请求,并产生随机的502网关错误。
现在我们在带有16个核心CPU和24GB DDR3 RAM的4个SAS 15k驱动器(raid10)的机器上运行Nginx(1.0.10)和PHP-FPM。 我们也使用最新的Xcache版本。 数据库位于另一台机器上,但是这台机器的负载很低,没有问题。
在正常的负载下,一切运行良好,系统负载低于1,并且PHP-FPM状态报告一次不会真正显示超过10个活动进程。 总是有大约10GB的内存仍然可用。 在正常的负载下,机器每秒处理大约100个综合浏览量。
当出现巨大的stream量峰值时,就会出现这个问题,并且要求机器每秒钟处理数百页的视图。 我注意到,FPM的状态报告显示了多达50个活动进程,但仍低于我们configuration的最大连接数300个。 在这些峰值期间,Nginx状态报告多达5000个活动连接,而不是正常的平均值1000。
OS信息:CentOS 5.7版(最终版)
CPU:Intel(R)Xeon(R)CPU E5620 @ 2.40GH(16核心)
PHP-fpm.conf
daemonize = yes listen = /tmp/fpm.sock pm = static pm.max_children = 300 pm.max_requests = 1000
我还没有设置rlimit_files,因为据我所知它应该使用系统默认,如果你不这样做。
fastcgi_params (只添加标准文件的值)
fastcgi_connect_timeout 60; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on; fastcgi_pass unix:/tmp/fpm.sock;
nginx.conf
worker_processes 8; worker_connections 16384; sendfile on; tcp_nopush on; keepalive_timeout 4;
Nginx通过Unix Socket连接到FPM。
sysctl.conf的
net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 1 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.tcp_timestamps = 0 net.ipv4.conf.all.rp_filter=1 net.ipv4.conf.default.rp_filter=1 net.ipv4.conf.eth0.rp_filter=1 net.ipv4.conf.lo.rp_filter=1 net.ipv4.ip_conntrack_max = 100000
limits.conf中
* soft nofile 65536 * hard nofile 65536
这些是以下命令的结果:
ulimit -n 65536 ulimit -Sn 65536 ulimit -Hn 65536 cat /proc/sys/fs/file-max 2390143
问题:如果PHP-FPM没有用完连接,负载仍然很低,并且有足够的RAM,在高stream量期间,这个随机的502网关错误会造成什么瓶颈?
注意:默认情况下,这台机器的ulimit是1024,因为我将其更改为65536我没有完全重启机器,因为它是一台生产机器,这意味着停机时间过长。
官方推荐:worker_processes =内核CPU数量
设置worker_processes 16;
来自负载平衡器(如HAProxy和nginx)的零星502错误通常是由LB和Web服务器之间的中间stream切断引起的。
尝试通过GDB运行您的一个Web服务器或其testing副本,看看您在生成testingstream量时是否出现分段错误(使用ab或jMeter或类似的模拟stream量)。
我最近不得不解决一个非常相似的情况/问题。 我排除了资源等问题,因为我有非常全面的监控,帮助我。 最后,我发现502错误是来自负载均衡器后面的web服务器返回无效(在这种情况下为空)对LB的HTTP响应。
我拿走了其中一台networking服务器并停止了networking服务器,然后通过gdb再次启动,然后浏览了该网站。 最终在点击一下后,我看到一个分段错误发生,这导致502错误是可见的。 我从GDB处取回了回溯,并将它提交给了PHP团队,但是唯一的解决方法是切换分布以解决PHP中的bug。
段错误导致Web服务器发送无效内容到LB,并且LB显示502错误,因为就其而言,Web服务器已经消失“中等stream量”。
我知道这不能直接回答你的问题,但是这是一个开始寻找的地方。 假设你看到一个段错误,你可以从GDB得到堆栈跟踪,那么你可以希望向后工作,找出导致段错误的function。