Java接口访问返回504错误_php进程超时接口返回504错误分析

  • Post author:
  • Post category:java


在一次接口测试中,发现返回的http 504 time out 的错误,然后查看了php-fpm的错误日志,发现了如下错误

[23-May-2018 13:33:14] WARNING: [pool www] child 19098, script ‘…./source/index.php’ (request: “POST /index.php?m=member&c=api&a=follow_phone_all”) execution timed out (4.473945 sec), terminating

[23-May-2018 13:33:14] WARNING: [pool www] child 19098 exited on signal 15 (SIGTERM) after 83279.781095 seconds from start

[23-May-2018 13:33:14] NOTICE: [pool www] child 31079 started

[23-May-2018 13:46:26] WARNING: [pool www] child 31079, script ‘…./source/index.php’ (request: “POST /index.php?m=aaa&c=bbb&a=ccc”) executing too slow (3.165423 sec), logging

[23-May-2018 13:46:26] NOTICE: child 31079 stopped for tracing

[23-May-2018 13:46:26] NOTICE: about to trace 31079

[23-May-2018 13:46:26] NOTICE: finished trace of 31079

[23-May-2018 13:46:27] WARNING: [pool www] child 31079, script ‘…./source/index.php’ (request: “POST /index.php?m=aaa&c=bbb&a=ccc”) execution timed out (4.166871 sec), terminating

从表现上看,是php进程超时导致的进程被kill了,那么这个超时时间以及kill的机制是跟哪些参数有关呢,这里系统这里一下。

Nginx服务一般因为php的错误或者超时会有两种错误码502 bad Gateway 或者 504 Gateway Time-out

1. 502 Bad Gateway

一种情况是php产生了语法错误,比如循环调用、变量作用域错误、方法不存在等,如果开启错误日志输出的话,这种错误在php-fpm的错误日志中是可以看到调用栈信息的。

另外一种情况可能就是超时引起的php-fpm主动kill的情况,在php.ini和php.fpm中有两个配置项,用来管理php脚本的最大执行时间

request_terminate_timeout = 3

request_slowlog_timeout = 3

当php脚本的执行时间超过这个时间时,PHP-FPM不只会终止脚本的执行,还会终止执行脚本的Worker进程。所以Nginx会发现与自己通信的连接断掉了,就会返回给客户端502错误。

以顶部的错误为例,当报502错误是,nginx的errorlog中有如下日志,:

2018/05/23 13:46:27 [error] 22374#22374: *88821697 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 111.202.106.229, server: test.api.xiaoka.tv, request: “POST /aa/bb/cc HTTP/1.1”, upstream: “fastcgi://unix:/dev/shm/php-fpm-71-wwww.sock”, host: “api.url.com”

2018/05/23 14:36:28 [error] 22377#22377: *88829729 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 111.202.106.229, server: test.api.xiaoka.tv, request: “POST aa/bb/cc HTTP/1.1”, upstream: “fastcgi://unix:/dev/shm/php-fpm-71-wwww.sock”, host: “tapi.url.com”

所以只需将这两项的值调大一些就可以让PHP脚本不会因为执行时间长而被终止了。request_terminate_timeout可以覆盖max_execution_time,

所以如果不想改全局的php.ini,那只改PHP-FPM的配置就可以了。

此外要注意的是Nginx的upstream模块中的max_fail和fail_timeout两项。这两个配置表示在fail_timeout事件内,如果fail的测试达到max_fail,那么在接下来的fail_timeout时间内,Nginx都会认为上游服务器挂掉了,都会返回502错误。

所以可以将max_fail调大一些,将fail_timeout调小一些。

2.504 Gateway Time-out错误

PHP-FPM设置的脚本最大执行时间已经够长了,但执行耗时PHP脚本时,发现Nginx报错从502变为504了。这是为什么呢?

因为我们修改的只是PHP的配置,Nginx中也有关于与上游服务器通信超时时间的配置

fastcgi_send_timeout 4;

fastcgi_read_timeout 4;

以Nginx超时时间为90秒,PHP-FPM超时时间为300秒为例,报504 Gateway Timeout错误时的Nginx错误访问日志如下:

2018/05/23 13:50:27 [error] 22374#22374: *88821697 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 111.202.106.229, server: test.api.xiaoka.tv, request: “POST /aa/bb/cc HTTP/1.1”, upstream: “fastcgi://unix:/dev/shm/php-fpm-71-wwww.sock”, host: “api.url.com”

调高这三项的值(主要是read和send两项,默认不配置的话Nginx会将超时时间设为60秒)之后,504错误也解决了。

而且这三项配置可以配置在http、server级别,也可以配置在location级别。担心影响其他应用的话,就配置在自己应用的location中吧。

要注意的是factcgi_connect/read/send_timeout是对FastCGI生效的,而proxy_connect/read/send_timeout是对proxy_pass生效的。



版权声明:本文为weixin_30705125原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。