告诉 nginx 在随机出现“502 Bad Gateway”时使用不同的 PHP 进程

告诉 nginx 在随机出现“502 Bad Gateway”时使用不同的 PHP 进程

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;
}

但这并不能解决您的问题,因为您需要在同一台服务器之间进行故障转移。

我建议你:

  1. 使用 TCP 套接字代替 UNIX 套接字,它们对于高并发更可靠、更稳定:

    upstream yourproject {
        server 127.0.0.1:9000;
    }
    

    您显然已在 php 池配置中将您的 php 指向此 TCP 套接字(listen = 127.0.0.1:9000

  2. 增加进程和 fd 限制/etc/limits.conf

    *    soft    nofile    65536
    *    hard    nofile    65536
    *    hard    nproc     65536
    *    soft    nproc     65536
    
  3. 增加net.core.somaxconn和。也许你已经到达极限了net.core.netdev_max_backlog/etc/sysctl.conf

  4. 如果您在 PHP 配置中使用pm = dynamic池,请检查这些参数并根据文档和系统资源进行调整:,,,pm.max_children。也许您也达到了极限。pm.start_serverspm.min_spare_serverspm.max_spare_servers

  5. 增加pm.max_requests你的 PHP 配置以避免重生过程发生得太频繁。

如果这不起作用,请复制并粘贴您的 PHP 和 Nginx 配置文件,以便更深入地了解它们。

相关内容