我有三台 Web 服务器,使用 nginx 作为前端,使用 php-cgi 作为后端。
我们使用 DNS 轮询来分配负载。在这台服务器中,我们有几个 PHP 应用程序,每个应用程序都存储在自己的文件夹中。
我们拥有大量潜在用户(员工人数约20000人)。
每个应用程序由不同的团队维护,因此可能使用不同的 PHP 框架。当其中一个应用程序的页面写得不好时,php-cgi 实例可能会卡住。当有足够多的人访问“坏”页面时,整个三台服务器都可能卡住。
是否有一种机制可以确定哪个 PHP 应用程序存在坏页面问题?
如果我可以确定哪个 php 页面正在由 php-cgi 进程运行,我就可以确定该页面属于哪个应用程序,并且可以停用有问题的应用程序,而不必看着整个系统崩溃。
问题是我还没找到如何监控正在运行的页面(仍然卡住)。如果只有一个应用程序,我可以更改它,我会在前端控制器的开始和结束时插入日志语句。如果应用程序超过 6 个,这种方法就不再实用了。
答案1
如果每个应用程序使用不同的虚拟主机名,
只需确保每个虚拟主机一个日志文件
另外,您还可以使用 URL 路径
SetEnvIf Request_URI /SOME_PATH_1 apps_1
SetEnvIf Request_URI /SOME_PATH_2 apps_2
CustomLog logs/apps_1.log env=apps_1
CustomLog logs/apps_2.log env=apps_2
必须有一些全局环境变量来唯一地标识每个应用程序。。
另外,您可以考虑设置较低的脚本超时时间。
将每个 Apache 请求的处理时间附加到日志文件中也可能有帮助。
答案2
以下方法可能会奏效。在所有网站的每个 PHP 文件的顶部,包含一行代码,将“SITE1_ERROR”写入服务器上所有三个网站扫描指向的一行文本文件。
在每个 PHP 文件的底部,编写一行代码,写入同一个文本文件,并用“SITE1_WORKING”覆盖“SITE1_ERROR”。
然后,由于 PHP 页面是从上到下处理的,如果页面从未完成处理(由于错误),至少文本文件将更新以显示哪个站点有错误。如果没有问题,文本文件应该始终显示“SITEX_WORKING”,其中 X 是站点的唯一标识符 #。
可能有比这更好的方法,但为什么不展示一下呢?最糟糕的情况是,每次成功调用 PHP 页面时,您都要两次写入文本文件。如果同时读取/写入一行文本文件是一个问题,或者太耗硬件/浪费时间,那么也许 MySQL 表记录更新或其他方法会更有效,只要所有三个站点可以共享同一个数据库表。