phpfpm优化方法(php-fpm超时时间设置request_terminate_timeout资源问题分析)
phpfpm优化方法
php-fpm超时时间设置request_terminate_timeout资源问题分析php日志中有一条超时的日志,但是我request_terminate_timeout中设置的是0,理论上应该没有超时时间才对。
php fatal error: maximum execution time of 30 seconds exceeded in ...
ok,先列出现在的配置:
php-fpm:
request_terminate_timeout = 0
php.ini:
max_execution_time = 30
先查阅了一下php-fpm文件中关于request_terminate_timeout的注释
; the timeout for serving a single request after which the worker process will
; be killed. this option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. a value of '0' means 'off'.
; available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; default value: 0
这个注释说明了,request_terminate_timeout 适用于,当max_execution_time由于某种原因无法终止脚本的时候,会把这个php-fpm请求干掉。
再看看max_execution_time的注释:这设置了脚本被解析器中止之前允许的最大执行时间,默认是30s。看样子,我这个请求应该是被max_execution_time这个设置干掉了。
好吧,不死心,做了一个实验:
php-fpm request_terminate_timeout 设置 | 0 | 15 |
php.ini max_execution_time 设置 | 30 | 30 |
执行结果 | php有fatal error超时日志,http状态码为500 | php无fatal error超时日志,http状态码为502,php-fpm日志中有杀掉子进程日志 |
好吧,结论是web请求php执行时间受到2方面控制,一个是php.ini的max_execution_time(要注意的是sleep,http请求等待响应的时间是不算的,这里算的是真正的执行时间),另一个是php-fpm request_terminate_timeout 设置,这个算的是请求开始n秒。
request_terminate_timeout引起的资源问题
request_terminate_timeout的值如果设置为0或者过长的时间,可能会引起file_get_contents的资源问题。
如果file_get_contents请求的远程资源如果反应过慢,file_get_contents就会一直卡在那里不会超时。我们知道php.ini 里面max_execution_time 可以设置 php 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。
真正能够控制 php 脚本最大执行时间的是 php-fpm.conf 配置文件中的request_terminate_timeout参数。
request_terminate_timeout默认值为 0 秒,也就是说,php 脚本会一直执行下去。
这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 nginx+php 的 webserver 已经无法再处理新的 php 请求了,
nginx 将给用户返回“502 bad gateway”。修改该参数,设置一个 php 脚本最大执行时间是必要的,
但是,治标不治本。例如改成 30s,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,webserver 同样很难避免”502 bad gateway”。
解决办法是:request_terminate_timeout设置为10s或者一个合理的值,
或者给file_get_contents加一个超时参数。
|
$ctx = stream_context_create( array ( 'http' => array ( 'timeout' => 10 //设置一个超时时间,单位为秒 ) )); file_get_contents ( $str , 0, $ctx ); |
php-fpm中的request_terminate_timeout最好不要设置
刚转到php-fpm没几天就发现,进入我的joomla后台,firefox偶尔会给我白屏的那种http 503,这种情况仅出现在天翼云的服务器上,而我在国外的同样配置的服务器一点问题都没有,后来发现是request_terminate_timeout的问题。
每次登陆joomla后台,joomla都会去检查是否有更新(检查成功后cache,默认保存该cache 6小时),而且分为joomla主程序和joomla扩展两个部分,如下图:
不出意外的话,服务器会发起两个php进程,分别分配给两个php-fpm children,去连接joomla的官方update服务器。好,问题就来了,我的request_terminate_timeout = 30s,30秒不完成则超时,参见天翼云主机的国际出口相当蛋疼!没错,30秒内,天翼云主机根本无法完成连接joomla更新服务器并检查是否有更新这整个过程。这也很好解释了为什么同样配置的国外服务器就没有问题,因为它们完成上述更细过程仅需要在2~5秒左右。
我的apache超时设置是30秒,php.ini中最长执行时间野是30秒,多年来都没有任何问题,没有30秒还打不开的网页,所以我就没多想给php-fpm的request_terminate_timeout = 30s。经过这次的事情发现此30秒非鄙30秒啊……
php-fpm设置request_terminate_timeout后,php.ini中的max_execution_time和max_input_time都会失效,以php-fpm中的设置为准;
apache+mod_php在timeout后,只会在日志中记录一下,仅此而已。php-fpm中的request_terminate_timeout超时之后,日志中记录http 503的同时,最要命的,它还会直接杀死造成这个http 503的php-fpm child,并生成新的child。
在我的joomla更新这个实例中,就会有两个php-fpm children同时被杀死。而我的天翼云主机是低配,只有一个cpu核心,我也只启动了两个php-fpm children,两个同时死了,我的firefox这边也就http 503 service unavailable的白屏了。php-fpm的error_log如下:
[27-sep-2014 10:41:06] warning: [pool www] child 1882, script '/home/onepx/public_html/administrator/index.php' (request: "post /administrator/index.php") execution timed out (30.004534 sec), terminating
[27-sep-2014 10:41:06] warning: [pool www] child 1882 exited on signal 15 (sigterm) after 164.717323 seconds from start
[27-sep-2014 10:41:06] notice: [pool www] child 1886 started
[27-sep-2014 10:41:06] warning: [pool www] child 1883, script '/home/onepx/public_html/administrator/index.php' (request: "post /administrator/index.php") execution timed out (30.005201 sec), terminating
[27-sep-2014 10:41:06] warning: [pool www] child 1883 exited on signal 15 (sigterm) after 166.718162 seconds from start
[27-sep-2014 10:41:06] notice: [pool www] child 1887 started
像joomla这种全php的网站,每个连接都需要apache+php-fpm协同运作。即便php-fpm中的request_terminate_timeout时间设置很长,apache中的timeout时间设置略短,只要apache的timeout到了,php-fpm照样在后面杀进程……
如果网站的访问者比较多,php-fpm的child是被许多访问者共用的,杀一个child,就有可能导致几个用户同时http 503 service unavailable。所以,我的建议是——php-fpm中的request_terminate_timeout最好不要设置,只给apache一个timeout就够了。
原文链接:https://www.cnblogs.com/hurry-up/p/9013389.html
- php-fpm配置文件在哪里(PHP-FPM 设置多pool及配置文件重写操作示例)
- phpfpm优化方法(php-fpm超时时间设置request_terminate_timeout资源问题分析)
- 这8种耐阴植物,营造阴生植物花境,也是一个不错的选择(营造阴生植物花境)
- 览邦G08 Plus SMART WATCH 测评⑱ 全独立这才是智能手表该有的样子(览邦G08PlusSMART)
- 荣耀手表 GS 3 真机亮相 不支持无线充电(荣耀手表GS3)
- 通过体温就能为智能手表充电 原来是用NASA在空间站用的黑科技(通过体温就能为智能手表充电)
- 智能手表兼容Windows和Android 无需充电挑战苹果(智能手表兼容Windows和Android)
- 一天一冲也算表 麦步,一款待机 21 天的智能手表体验评测(一天一冲也算表)
热门推荐
- python 迭代对象必须实现哪些方法(详解python之heapq模块及排序操作)
- C# volatile与lock
- linux怎么退出括号模式(Linux使用stty显示修改终端行设置)
- mysql效率查询(MySQL 如何分析查询性能)
- web服务器的配置教程(服务器的配置 web服务器配置方法步骤详解)
- 数据库sqlserver定时任务(SQL Server 2005作业设置定时任务)
- nginx配置ip端口访问(Nginx配置80端口访问8080及项目名地址方法解析)
- css定位总结(css中的三种基本定位机制)
- 织梦dede数据库(dedeCMS 织梦的日期时间格式大全最新)
- python获取系统的utc时间(Python的UTC时间转换讲解)