测试环境:虚拟机centos7,nginx+php
压测工具:Apipost
访问的php程序中添加sleep()增加程序执行时长,使用Apipost进行压测,根据服务器配置设置一个大概可能触发报错的并发和轮训次数,若无报错逐渐增加并发和次数,同时监测nginx错误日志,触发报错。
1.压测报错:recv( )failed (104: Connection reset by peer) while reading response header from upstream
优化方案:
①关闭selinux,编辑 /etc/selinux/config
文件,将 SELINUX=enforcing
改为 SELINUX=disabled
,保存并退出,重启服务器(修改完下面第②条再一块重启吧)使其生效。如果改错了,重启卡在了进度条,参考文档:因为错误关闭Selinux导致CentOS7启动失败(进度条卡死,图形界面加载卡死)-CSDN博客
别问我怎么知道的
②编辑/etc/sysctl.conf文件添加如下配置:
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 1024
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
什么意思?
看了文章也不是全部理解,所以自己研究,说不定有自己的心得。
③有的文章对该报错说编辑nginx.conf添加或增大buffer大小:
proxy_buffering on;proxy_buffer_size 4k;proxy_buffers 4 32k;proxy_busy_buffers_size 64k;proxy_temp_file_write_size 64k;
这里的值根据服务器配置和业务量情况进行调整,不过后续测试把这里去掉也不会报104错误,所以仅供参考。
做完以上修改后,再次使用Apipost没有再次报104错误了,这里说的是相同或稍微增大压测量的情况,不排除大幅度增加并发请求量仍会出现104报错的可能。
2.压测报错2:upstream time out (110: Connection timed out) while reading response header from upstream
该110报错有时候伴随着上面的104出现,也可能单独出现。
针对该报错进行了如下测试:
### 测试情况1:
Php-fpm配置pm.max_children=50,
nginx配置:
fastcgi_connect_timeout 10;
fastcgi_read_timeout 60;
压测工具Apipost,测试300并发,轮循5次,
Nginx110报错数:579
### 测试情况2:
Php-fpm配置pm.max_children=100,
nginx配置:
fastcgi_connect_timeout 10;
fastcgi_read_timeout 60;
压测工具Apipost,测试300并发,轮循5次,
Nginx110报错数:238
### 测试情况3:
Php-fpm配置pm.max_children=100,
nginx配置:
fastcgi_connect_timeout 30;
fastcgi_read_timeout 60;
压测工具Apipost,测试300并发,轮循5次,
Nginx110报错数:0
这里的请求失败数和错误率不一定是程序报错,下面再讲解,检测nginx报错日志是没有报错的。
测试总结:
(110: Connection timed out)字面意思就是连接超时,通过以上测试大概能理解,出现该报错应该是php-fpm进程已达到最大值且已被占满,并且后续大量请求堆积无法在fastcgi_connect_timeout 设置的时间内抢占到php-fpm进程资源导致的超时报错,所以测试2增大了php进程数,提高了请求的消费能力在一定程度上减少了请求堆积情况,而测试3增大了fastcgi_connect_timeout的值,这就给等待处理的请求更宽裕的时间去连接php-fpm进程,提高了容错能力。这个数值肯定不是越大越好,这会增加这些请求的整个响应周期的时长(错误响应也是响应),长时间处于过长时间的等待连接就已经表明需要提高服务进程数或着提高服务器配置了,同时超长时间的请求响应到用户这里可能早就已经不需要或被丢弃了,同时还占用着本来就已经紧张的服务器资源,可以说是雪上加霜。在服务器资源充足的情况的可以通过增加服务进程来提升请求处理能力,在服务器资源枯竭的情况就应该考虑提升服务器配置,如果提升配置到一定瓶颈仍处理不过来,就需要考虑增加服务器数量了。
3.就Apipost失败请求数问题测试。
在上述测试情况3的条件再次压测:
查看nginx访问日志,发现499响应码:
统计499数量:grep "499" access.log | wc -l
刚好7,对应Apipost失败请求数,
搜索http 499状态码:
应该属于Apipost自己的超时策略,主动切断请求导致的499,被视为失败请求。
结合测试2、测试3也刚好应验了把fastcgi_connect_timeout 扩大,会降低nginx报错,但是会拉长这些请求的整个请求周期的时间,在Apipost可能会因为超时被视为失败请求,而结果是失败率变大。
###校验499触发
将nginx配置fastcgi_read_timeout 120;
Php代码中添加sleep(100);
ApiPost压测缩减为10并发2轮
同时用浏览器访问接口
Apipost只耗时40s结束,全部失败,错误率100%
Nginx访问日志全为499响应码
反观浏览器则等待100s返回正常结果,nginx日志也是200响应码
所以apipost压缩应该是有一定的超时策略的,按上述结果应该每个请求超过20s未响应视为失败。