我让 PHP-FPM 在 Unix 域套接字上监听,并且我已经www
使用以下值配置了池(唯一存在的池):
slowlog = /$pool.log.slow
request_slowlog_timeout = 10s
为了测试,我将 max_execution_time 设置php.ini
为 20 秒。然后我创建了一个测试脚本:
<?php
while(1){
$i++;
}
?>
然后通过 Web 浏览器访问它。脚本最终由于以下原因超时,max_execution_time
但日志仍为空:
root@b7e4a919c988:/var/www/html# ll /www.log.slow
-rw-rw-rw-. 1 www-data root 0 Jan 4 21:31 /www.log.slow
但是 PHP-FPM 日志似乎表明它期望记录缓慢的运行:
[04-Jan-2018 21:37:28] WARNING: [pool www] child 9382, script '/var/www/html/test.php' (request: "GET /test.php") executing too slow (13.061999 sec), logging
我尝试了各种方法,例如使用sleep(10000)
或将while
循环放入函数中(以防它无法构建堆栈跟踪),但似乎没有什么能让它将回溯打印到日志中。日志文件本身的存在似乎也表明 FPM 预计会写入慢速请求。
此刻我只是不知道还要检查什么。
答案1
经过一番折腾,我终于找到了问题所在。问题在于,在 Linux 上,PHP-FPM 用于SYS_PTRACE
跟踪工作进程(我猜这是它检索跟踪数据的方式),但docker
容器默认不允许此功能。
有一次,我使用该选项运行了 docker 容器,并配置了OP 中提到的--cap-add=SYS_PTRACE
两个设置(和)。www.conf
slowlog
request_slowlog_timeout
与我见过的其他 SO 答案相反,我从来不需要启用catch_workers_output
它就可以让它工作。
上述脚本会生成以下输出到 slowlog:
[09-Jan-2018 17:30:39] [pool www] pid 9382
script_filename = /var/www/html/work.php
但为了生成更真实的函数轨迹,我写了这个小数字:
<?php
function callsSlowFunc(){
for ($i=0; $i<=10; $i++){
slowFunc();
}
}
function slowFunc(){
for ($j=0; $j <= 50000000; $j++){
$hey="there";
}
}
callsSlowFunc();
这将导致生成以下函数跟踪:
[09-Jan-2018 17:40:49] [pool www] pid 9382
script_filename = /var/www/html/work.php
[0x00007fee53613150] slowFunc() /var/www/html/work.php:6
[0x00007fee536130a0] callsSlowFunc() /var/www/html/work.php:19