我们正在使用 FastCgi 在 iis 上运行多个 php 站点。某些站点现在生成许多 FastCgi 实例,这些实例的 CPU 使用率很高。不幸的是,所有站点都从网络服务运行,我们看不到哪个 W3WP 进程生成了哪个 FastCgi 进程。
有没有什么方法可以识别 FastCgi 并将其追踪到特定的 AppPool 或网站?
答案1
Sysinternals Suite 的进程浏览器可在 Ms Technet 中作为第一条评论使用。
http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx
花足够的时间使用这些工具。选择“查看”>“显示句柄”。然后您将看到下部面板显示 iis 服务当前使用的所有 IPC 和打开的文件和端口。套件版本中还提供命令行工具,用于通过 IPC 进行编程解决方案。所有以 Ps* 开头的工具都可以为您提供足够的信息。
对于 Linux 用户来说:Process Explorer 是类似 top/htop 的进程列表工具,具有 lsof 功能。
答案2
我实际上认为这是使用 apache 和 mod_php 而不是 fastcgi 的最佳理由之一。当您遇到性能危机时,这一点非常重要。我偶尔会考虑研究如何在 php_fpm 中实现这一点,但还没有时间这样做。
不幸的是,我的答案是基于 Linux 的,这可能对你没有帮助(假设你引用了 IIS)。无论如何,我都会把答案贴出来,也许我提到的工具有 Windows 版本)
您可以在 php 处理的开始处放置一些内容来设置一些临时功能,这些内容会记录收到的 URL、PHP 进程的进程 ID 以及其他一些详细信息(例如时间)。您还可以记录处理的完成情况,如果您不能依赖针对所有 PHP 请求进行的记录,那么这一点就尤为重要。
我还没有找到一个好的方法将该 URL 和堆栈前端连接到 PHP 进程,但我已经成功地通过跟踪 lsof 中的套接字 ID 从 Postgresql 进程跟踪回 PHP 进程。每个 postgresql 会话都由一个单独的进程处理,这使得这更容易。我不知道如何对 mysql 做同样的事情,但我也没有在这方面投入太多精力。除了跟踪套接字 ID,您还可以通过在数据包数据中查找查询,然后查看哪些进程持有与您感兴趣的流量相关的端口 ID 来取得进展。
另一种方法(据我所知,在 Linux 上最有用的方法)是查看使用所有 CPU 的 php 进程内部发生了什么。这里的主要工具是 strace 和 ltrace。请注意,这样做会施加额外的 CPU 和 IO 负载,但您可以附加一个进程来记录与您感兴趣的进程相关的系统调用(strace)或库函数调用(ltrace)。它并不总是有效,因为您可能会让进程陷入紧密的循环中,而不会调用系统或其他库,但这通常会让您得到所需的东西。
我还没有真正深入研究过这个问题,但我认为如果您使用 php-dev 将 gdb 之类的东西附加到将要停止的进程,然后您可以查看堆栈,这也是可能的。您将获得一个 C 语言堆栈而不是 PHP 堆栈,但大概您可以在其中找到 php 函数的名称并找出涉及哪些函数。正如我所说,您必须暂停执行,但如果您编写了某些脚本来附加 gdb、打印出堆栈列表并断开连接,您就不必中断太多事情。我怀疑 C、C++ 和 C# 等语言的程序员使用的 Windows 调试工具可以做到这一点?
值得研究一下您可以从各种 PHP 调试器中获得什么。
所以这并不是您真正想要的,但也许您现在对解决弄清楚活动过程中发生的事情的问题的其他方法有了一些想法。
也许有人可以指出一些与我使用的 Linux 工具等效的 Windows 工具?