我们一直在使用 NGINX 和 php-fpm。
我们注意到有些请求挂起很长时间(10 分钟以上、20 分钟以上……)顶部命令。
此外,在访问日志条目(NGINX)中检测到了一些可疑请求(我的意思是机器人),但我不确定这些可疑请求是否与那些挂起的请求有关。
所以我的主要问题是:
是否可以(通过配置或其他方式)将 php-fpm PID 关联到访问日志中的 URL 条目?
或者有什么工具可以帮助我完成这项任务?
附加信息:
我们拥有源代码,因为我们是主要开发人员。
提前致谢!
答案1
从 nginx 端识别正确的 php-fpm 进程是有问题的,因为你本质上是通过 unix 套接字或 tcp 套接字与黑盒进行通信,更不用说线程了。
您可以从 php 方面解决问题。您可以使用 php 脚本中的 getmypid(),或者如果这不是您的代码,您可以在 php fpm 配置中使用 php_value auto_prepend_file 选项。这样,您可以在每个 php 文件的开头插入自己的代码,并根据需要记录 pid 以及相应的 REQUEST_URI。您有所需的连接。不过,请准备好在繁忙的网站上使用大量 iops...
如果你只需要 pid,那么启用 php-status 可能会更容易,如这里所述https://easyengine.io/tutorials/php/fpm-status-page/并检查你的服务器/php-status?full
答案2
RequestId
通常,使用所谓的只需设置两个标题来处理此类问题:X-REQUEST-ID
并将X-CORRELATION-ID
它们添加到 nginx 和 php 端的日志中。
RequestId
应在每个请求开始时设置为一个随机值(我使用 UUID),并CorrelationId
应在每次用户交互时将其设置为一个随机值。对于小型网站,通常只有一个RequestID
和一个CorrelationId
。如果您使用微服务,那么每个微服务都会生成自己的RequestId
,但CorrelationId
它们之间会共享。
实施取决于您的基础设施,但简单的实施可能看起来像这样:
# in nginx config
location / {
proxy_pass http://upstream;
proxy_set_header X-Request-Id $request_id;
...
}
# or
location / {
fastcgi_pass unix:/path/to/socket;
fastcgi_param HTTP_X_REQUEST_ID $request_id;
...
}
# This works because nginx generates a random string and stores it as $request_id
然后只需在 PHP 中记录你的 pid:
# in php-fpm config
# %p - pid
access.format = "[%p][%{HTTP_X_REQUEST_ID}e] %R - %u %t \"%m %r\" %s"
# or in php application itself
# index.php
<?php
file_put_contents('somewhere.log', sprintf('[%s][%d]', $_SERVER['HTTP_X_REQUEST_ID'] ?? 'N/A', getmypid()), FILE_APPEND);
...
答案3
如果您启用了 php-fpm 状态页面,您可以考虑检查完整模式来跟踪 pid。例如,使用http://example.com/phpfpm-status?full应该能够发现发生了什么。(出于安全考虑:永远不要让此类状态页面公开。)
答案4
你应该利用 PHP-FPM 的 slow-log: 设置request_slowlog_timeout
-slowlog
参见php-fpm 配置文档- 应该为您提供所有长时间运行的 php-fpm 进程的堆栈跟踪;包括它们的 PID。