告訴 nginx 在隨機“502 Bad Gateway”上使用不同的 PHP 程序
在網路伺服器上,通常可以很好地與
nginx
andphp-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
。如果 webserver 程序可以對 PHP 故障做出反應,它可以 (a) 殺死特別損壞的程序並 (b) 嘗試另一個程序,而不是拋出 502 Bad Gatway。到目前為止,我還沒有找到
nginx
對失敗做出反應的選項。誰知道如何實現這一目標?還是有更簡單的解決方案,我錯過了?connect() to unix:/run/php/php7.0-fpm.sock failed (11: Resource temporarily unavailable)
您不能將請求從一個程序移動到同一上游內的另一個程序,但您可以將其從一個上游移動到另一個。
首先,您至少需要兩個上游(您將需要兩個不同的 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
) 2. 增加程序和 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
。也許你已經達到了極限。- 如果您
pm = dynamic
在 PHP 配置池中使用,請檢查此參數並根據文件和系統資源進行調整:pm.max_children
,pm.start_servers
,pm.min_spare_servers
,pm.max_spare_servers
. 也許你也達到了極限。- 增加
pm.max_requests
您的 PHP 配置以避免重生過程過於頻繁地發生。如果這不起作用,請複制並粘貼您的 PHP 和 Nginx 配置文件,以更深入地了解它們。