前段时间同事告诉我,PHP脚本的超时时间是fpm配置优先考虑的。自己测试了一下,其实不是这样的。前面的观点只在特定情况下才成立。php脚本超时可以在php.ini的max_execution_time和fpm.conf的request_terminate_timeout参数中设置。那么两者有什么区别呢?当我们设置php.ini的max_execution_time参数时,zend引擎在处理脚本时,会根据设定的时间在内部定义一个定时器(setitimer),这是linux的API。fpm.confrequest_terminate_timeout的检测是通过主进程遍历定时事件fpm_pctl_heartbeat来判断PHP脚本执行是否超时。下面举例分析。示例:$a=time();var_dump('begin');for($i=0;;$i++){if(time()-$a>10){break;}}var_dump('结束');上面的代码比较容易理解。首先输出“begin”字符串,10秒后输出“end”字符串。方案一:修改php.ini中的配置max_execution_time=3,fpm.conf.example中的request_terminate_timeout=20执行结果:string(5)"begin"1Chrome浏览器抓包:根据以上运行结果和效果图,可以看出,示例运行3秒后终止。也就是说,此时php.ini的max_execution_time生效。方案二:修改php.ini中的配置max_execution_time=20,fpm.conf中的request_terminate_timeout=3。执行结果示例:chrome浏览器抓包:从上面的截图可以看出,程序只执行了3S。此时脚本的运行受fpm.conf的request_terminate_timeout配置的影响。从以上两种方案可以看出,对于example实例,PHP脚本取max_execution_time和request_terminate_timeout中的最小值作为脚本的超时时间。那只需要设置max_execution_time参数吗?下面继续分析,我们稍微调整一下示例代码。$a=time();var_dump('开始');睡眠(10);var_dump('结束');这段代码和上面的函数类似,唯一不同的是循环改成了sleep()。使用方案一的配置,结果如下:string(5)"begin"string(3)"end"1采用方案二的配置,结果如下:示例执行结果:比较两个结果,我们可以看到此时max_execution_time的配置没有起作用。以下是引用自php手册(http://php.net/manual/zh/func...):set_time_limit()函数和配置指令max_execution_time只影响脚本本身的执行时间。任何出现如使用system()系统调用、流操作、数据库操作等脚本执行的最大时间不包括在脚本已经运行的情况下。在Windows中测量的时间是一个真实值时,情况并非如此。所以,在为了保证生产环境的安全,建议同时设置max_execution_time和request_terminate_timeout参数值。
