nginx
在通常与配合良好的 Web 服务器上php-fpm
(当前版本为 7.0.22,但这与版本基本无关),有时会出现 502 Bad Gateway。这通常意味着:其中一个进程php-fpm
崩溃,并且nginx
未收到所选进程的答复。
我的当前解决方法不仅要监视php-fpm
进程,还要监视 PHP 页面的输出。如果这在 4 分钟内不起作用(两次重试失败,监视间隔为 2 分钟),则将monit
终止所有php-fpm
进程并重新启动php-fpm
服务。有效,但仍会导致 5 分钟的停机时间(至少对于连接到损坏进程的一些用户而言)或更长时间,因为monit
在观察到 502 Bad Gateway 之前,还不如多次看到来自正常进程的答案。
(1) 理想的解决方案是修复任何中断进程的错误php-fpm
。但是,错误很少发生,所以我无法将其追溯到某个特定原因。可能是 PHP 脚本中的内存泄漏...我不知道。
(2) 我认为,第二个最佳选择是需要一些合作nginx
。如果 Web 服务器进程能够对 PHP 故障做出反应,它可以 (a) 终止具体损坏的进程,并且 (b) 尝试另一个进程,而不是抛出 502 Bad Gatway。
到目前为止,我还没有找到nginx
对失败做出反应的选项。谁知道如何实现这一点?或者有没有我没注意到的更简单的解决方案?
connect() to unix:/run/php/php7.0-fpm.sock failed (11: Resource temporarily unavailable)
答案1
你不能将请求从同一上游的一个进程移动到另一个进程,但你能将其从一个上游移动到另一个上游。
首先,您至少需要两个上游(您将需要两个不同的 php 池):
upstream yourproject {
server unix:/run/php/php7.0-fpm_primary.sock;
server unix:/run/php/php7.0-fpm_secondary.sock;
}
然后您可以配置它们之间的故障转移:
location ~ \.php$ {
# First, you need to capture fastcgi errors
fastcgi_intercept_errors on;
# Specifies in which cases a request should be passed to the next server
fastcgi_next_upstream error timeout http_500 http_503;
# Limits the time during which a request can be passed
# to the next server
fastcgi_next_upstream_timeout 10s;
# Limits the number of possible tries for passing
# a request to the next server
fastcgi_next_upstream_tries 2;
fastcgi_pass yourproject;
}
但这并不能解决您的问题,因为您需要在同一台服务器之间进行故障转移。
我建议你:
使用 TCP 套接字代替 UNIX 套接字,它们对于高并发更可靠、更稳定:
upstream yourproject { server 127.0.0.1:9000; }
您显然已在 php 池配置中将您的 php 指向此 TCP 套接字(
listen = 127.0.0.1:9000
)增加进程和 fd 限制
/etc/limits.conf
:* soft nofile 65536 * hard nofile 65536 * hard nproc 65536 * soft nproc 65536
增加
net.core.somaxconn
和。也许你已经到达极限了net.core.netdev_max_backlog
。/etc/sysctl.conf
如果您在 PHP 配置中使用
pm = dynamic
池,请检查这些参数并根据文档和系统资源进行调整:,,,pm.max_children
。也许您也达到了极限。pm.start_servers
pm.min_spare_servers
pm.max_spare_servers
增加
pm.max_requests
你的 PHP 配置以避免重生过程发生得太频繁。
如果这不起作用,请复制并粘贴您的 PHP 和 Nginx 配置文件,以便更深入地了解它们。