我在一台 1GB 单核 VPS 上运行 Drupal 6、Nginx 1.5.1 和 PHP-FPM(PHP 5.3.26),SSD 存储上有 3GB 交换空间。我刚刚从共享主机切换到这个非托管 VPS,因为我的网站变得太重了,所以我还在学习相关知识。我的流量相当高,我并没有密切监控它,但 Google Adsense 通常记录接近 30K 页面浏览量/天。我通常有 50 到 80 个经过身份验证的用户登录,并且有几百个匿名用户随时访问 Boost 静态 HTML 缓存。
我遇到的问题是 PHP-FPM 经常停止响应,导致 Nginx 502 或 504 错误。我发誓我已经阅读了互联网上关于这个问题的每一页,这个问题似乎相当普遍,我尝试了无数种配置组合,但找不到好的解决方案。重新启动 Nginx 和 PHP-FPM 后,网站运行了一段时间,非常快,然后在没有任何警告的情况下停止响应。浏览器在服务器上等待时出现白屏,大约 30 秒到 1 分钟后,它会抛出 Nginx 502 或 504 错误。有时它可以正常运行 2 分钟,有时 5 分钟,有时 5 小时,但总是挂起。当我发现服务器处于这种状态时,仍然有大量可用内存(>500MB 或更多)并且没有主要的 CPU 使用率,控制和工作 PHP-FPM 进程仍然存在,并且服务器仍然可以通过 SSH 进行 ping 和使用。通过 init 脚本重新加载 PHP-FPM 可使其恢复。挂断似乎与流量大小无关,因为当我在没有任何流量的开发 VPS 上测试此配置时,我始终观察到这种行为。
我一直在不断调整设置,但无法彻底消除问题。我将 Nginx 工作进程设置为 1。在 PHP-FPM 配置中,我尝试了所有三个进程管理器。“动态”绝对是最不可靠的,几分钟后就会一直挂断。“静态”也不可靠,而且不可预测。问题最少的是“按需”,但即使是它也让我失望,有时甚至需要 12 到 24 小时。但我不能让服务器无人看管,因为 PHP-FPM 会死机,并且永远不会自行恢复。我尝试将 pm.max_children 值从低至 3 调整到高至 50,没有太大区别,但我目前将其设置为 10。备用服务器值也是一样。我还将 pm.max_requests 设置为从 30 到无限制的任意值,但似乎没有什么区别。
我也一直在使用 APC 和 Redis 缓存来减轻数据库的一些负载,但无论是否激活这些机制,PHP-FPM 问题都存在。
根据日志,PHP-FPM 进程不是通过 SIGSEGV 或 SIGBUS 退出的,而是通过 SIGTERM 退出的。我收到很多类似这样的行:
WARNING: [pool www] child 3739, script '/var/www/drupal6/index.php' (request: "GET /index.php") execution timed out (38.739494 sec), terminating
和:
WARNING: [pool www] child 3738 exited on signal 15 (SIGTERM) after 50.004380 seconds from start
实际上,我发现有几篇文章建议每隔几分钟或几小时通过 cron 优雅地重新加载 PHP-FPM,以规避此问题。所以我每 5 分钟执行一次“/etc/init.d/php-fpm reload”。到目前为止,它一直亮着。但感觉像是一个可怕的黑客行为。PHP-FPM 真的那么不可靠吗?我还能做些什么吗?非常感谢!
答案1
您是否尝试过其他优化器或尝试过使用 apc.filter?这听起来确实像是一个与 APC 相关的问题,因为 APC 的稳定性始终取决于所使用的代码和 apc 配置。
答案2
通过谷歌搜索来到这里,分享一些经验。
遇到了同样的问题,不过是在 Drupal 7 中!(抱歉 @michael Hampton ;-) Drupal 6 在相同的 VPS(2048 MB、2× 2.4Ghz@60%、NGINX、APC)上运行良好。Drupal 7 在大约 4 小时后卡住,就像交通堵塞或类似情况 ;-) 两周以来,我一直在尝试和寻找不同的解决方案。
看来禁用 APC 终于奏效了。之前(启用 APC 时),Drupal 中的 CRON 在慢速日志中出现错误。没有 APC 时,网站似乎快一点。