nginx+php-fpm 长时间运行php脚本,需要配置如下:
长时间运行错误说明:
499:客户端(或者proxy)主动断开连接
504:网关超时:(Gateway Timeout)
502:网关错误(Bad Gateway)
502 网关错误(Bad Gateway)
- 因为webserver reject(iptables -I INPUT -s xxx.xxx.xxx.xxx -j REJECT)了proxy的包;
- 与drop不同之处在于,这个时候webserver会返回一个端口不可达的ICMP包给proxy,proxy会重试一次后返回 502 给客户端,超时时间约为1秒。
504 网关超时
-
必要配置 (单位都是: 秒)
proxy的nginx.conf中 proxy_read_timeout=60 webserver的nginx.conf中 fastcgi_read_timeout=300 php-fpm中的 request_terminate_timeout=120
-
php执行时间超过proxy的
proxy_read_timeout
假设php-fpm有一个test.php
执行时间为100
秒,超过了默认的proxy_read_timeout=60
,则到1分钟后proxy会关闭到webserver的连接,webserver记录的返回码为499
,proxy的返回码为504
,客户端看到的返回码也就是504
。 -
php执行时间超过webserver的
fastcgi_read_timeout
假如设置fastcgi_read_timeout=10
,test.php执行时间100秒
,则10秒后webserver会关闭和PHP的连接,webserver记录日志的返回码为 504,proxy日志的返回码也是504
。 -
php执行时间超过
php-fpm
的request_terminate_timeout
- 设置
request_terminate_timeout=5
,test.php还是执行100秒
,可以发现5秒之后,php-fpm会终止对应的php子进程,webserver日志的状态码为 404,proxy的日志的状态码也是 404。 -
特别注意: 在php-fpm模式中,
php.ini
中的max_execution_time
参数无效。
- 设置
我的nginx配置: ngixn.conf
- 注意:我这里把
proxy_buffering off
和proxy_buffering off
,两个缓冲区关闭了。
server {
listen 8001;
index index.php index.html;
server_name _;
root /var/www/dal;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_buffering off;
location / {
index index.html index.htm index.php l.php;
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
}
location ~ \.php(.*)$ {
#try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffering off;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
access_log /var/log/nginx/dal-access.log;
error_log /var/log/nginx/dal-error.log;
}
我的php-fpm配置 www.conf
request_terminate_timeout = 600
test.php运行前建议添加如下函数:
<?php
set_time_limit(0); //php长时间运行
ob_flush(); //刷php缓存
flush(); //刷系统层面的缓存
/* php 程序*/
?>
踩坑记录
- 我配置完毕后,跑程序,使用的测试api的工具是
apifox
; - 每次跑 test.php 时(执行时间=200秒),都没有任何响应信息。
- 对应的
php-fpm
和nginx
也没有任何错误日志,最后改用jmeter
测试,一次通过; - 最后发现:没有配置apifox自身的超时时间。
总结:
- 长时间运行脚本建议使用shell, 但是本人感觉shell不是很严谨,可以考虑使用原生php脚本,也就是不过nginx和webserver, 不依赖任何框架.
- 批处理数据属于性能测试范围了,所以最好使用性能测试工具
jmeter
网友评论