NGINX+PHP-FPM:是否可以关联 php-fpm PID 来访问日志条目?

NGINX+PHP-FPM:是否可以关联 php-fpm PID 来访问日志条目?

我们一直在使用 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。

相关内容