看来如果php的worker进程执行超时,不仅终止脚本执行,而且worker进程也会退出。看来nginx的报错连接被重置是因为php的worker进程退出了(在TCP连接中一方如果断掉的话会发送RST给另一方)
通过日志已经可以知道php脚本执行超时,worker子进程退出,导致nginx报错Connection reset by peer,下边我们通过strace来看看php和nginx的情况:
php:

1.accept一个nginx的连接请求(socket,bind,listen都在master中完成 ),可以看到nginx的端口是47039,从FD0中读取数据,就是从标准输入中,这个是fast-cgi协议规定的。accept之后的已连接描述符是3。
2.从FD3中读取nginx传递过来的数据,fastcgi协议格式,接收了856字节。为什么read5次呢?
因为fastcgi协议数据包是8字节对齐,由包头和包体组成。并且都是会先发一个request数据包,包含一些请求ID,版本,typpe等信息(包头包体各占8字节),再发一个params数据包,传递get参数和环境变量(包头8字节,包体变长),最后发送一个没有包体只有包头的params数据包,表示参数发送结束(包头8字节)。所以前3个read用来读出request包的包头和包体,还有params包的包头,第四个read是读取真正的数据,最后一个read是读取最后一个params包的包头。所以nginx传递的数据应该是8+8+8+856+8=896字节(和下边nginx的传输bytes能对应上)。注意如果是post方式,还会发送stdin数据包。
3.设置休眠20S,就是php程序中的sleep(20),之后由于进程被终止了,所以后边就没啦。strace程序也退出啦。
nginx:

1.accept到浏览器的请求,可以看到浏览器端的端口是56434,IP是192.168.1.105,已建立连接的FD是3。
2.从FD3中接收数据,HTTP协议。
3.创建一个socket,FD21,用于和php建立连接。
4.连接到FD21,可以看到连接的是本机的9000端口,这里nginx和php-fpm使用IP socket连接方式,nginx和php-fpm部署在一台机器上可以考虑unix domain socket。
5.向FD21写入数据,fast-cgi协议格式,我们看到写入的长度是896,和上边的php接收的长度是对应的。
6.recvfrom函数从FD21中返回 ECONNRESET (Connection reset by peer)
7.向FD9中写入错误信息,可以推断FD9就是nginx错误日志的文件描述符。
8.关闭和FD21的连接。
9.向FD3写入502 Bad Gateway,就是返回给浏览器的信息。
10.向FD8写入一条访问日志,可以推断FD8就是nginx访问日志的文件描述符。
来验证一下nginx访问日志和错误日志的推断。可以看到的确是FD8,FD9,并处于写入模式。








