nginx是IT工程师常用的组件,nginx有很多功能,其中一项就是可以将请求反向代理至后端的服务器来进行具体的逻辑处理,完成之后再由nginx将结果返回给客户端。
正常实验
接下来我们通过实验来得到结论
实验思路
对nginx + php 环境的一个简单脚本进行压力测试,压力测试的过程中同时检查 nginx服务器、php服务器 9000端口的使用情况,得出最后的结论。
实验脚本
test.php
<?php
var_dump("Hello Word!");
?>
压力测试
网络监控
在nginx和php服务器上分别执行以下命令,获取网络连接的状态
netstat -anpt | grep :9000
nginx网络连接状态
PHP网络连接状态
以上两个图的红框部分为nginx进程与php进程网络通信中使用的nginx服务器的IP和端口,我本地的nginx进程有 1 个、php-fpm进程最大 5 个,如此多的端口足以证明:nginx中fastcgi与php-fpm进程的网络通信为 短连接 。
TCP主动关闭方与被动关闭方的思考
上面实验压力测试的结果为:
红框部分为请求失败的数量。我们的结果为 0 ,这个结果表明所有的请求都是正常的,没有发生 502 或 504 的现象。
此时观察上面nginx、php服务器的截图,网络连接状态一栏。
nginx状态为 CLOSE_WAIT 、 LAST_ACK 。表明nginx端的网络连接为 TCP被动关闭方 。
PHP状态为 TIME_WAIT 。表明php端的网络连接为 TCP主动关闭方 。
异常实验
生产环境中我们也偶尔会碰到nginx的网络状态出现 FIN_WAIT1 、 FIN_WAIT2 这种主动关闭方的状态;同时PHP的网络状态出现 CLOSE_WAIT 的这种被动关闭方的状态。我们通过实验来复现一下这个结果。
测试脚本
<?php
var_dump("Hello Word!");
sleep(3);
?>
压力测试
ab -c 100 -n 100
压力测试结果
上图红框内失败的请求为 44 个。
网络截图
在nginx和php服务器上分别执行以下命令,获取网络连接的状态
netstat -anpt | grep :9000
nginx网络连接状态
nginx网络链接出现主动关闭状态 FIN_WAIT2 。
php网络连接状态
php网络连接出现被动关闭状态 CLOSE_WAIT 。
原因
当服务器压力过大的时候(以上我们用sleep模拟慢接口),php-fpm处理不过来nginx服务器发送过来的请求。nginx中fastcgi有请求的超时处理机制,fastcgi中的请求如果在等待php-fpm响应的过程中没有在超时前得到结果,就会发送 Fin包 给php-fpm保持的网络请求端,关闭连接,所以这时候nginx服务器上的网络请求就会成为网络连接的主动关闭方,所以出现 FIN_WAIT2 状态。