nginx+php-fpm服務HTTP狀態碼502怎麼解決
我們的一個web項目,由於新上城市增多,導致訪問量增大,db壓力增大,作為提供接口的業務方,最近被下游反饋大量請求“502”。
502,bad gateway,通常都是upstream(這裡就是php)出錯,對於php,造成502的原因常見的就是腳本執行超過timeout設定時間,或是timeout設定過大,導致php進程長時間不能被釋放,沒有空閒worker進程來接客。
我們的專案就是php執行時間設定過短導致的,對於這種情況,可以先適當增大php的執行時間,先保證清除502,優化的事情畢竟要花更多的時間。
控制php執行時間的選項有兩個,在php.ini中max_execution_time 和php-fpm中request_terminate_timeout,其中request_terminate_timeout 可以覆寫max_execution_time,所以如果不想改全域的php.ini,那隻改php- fpm的配置就可以了。
下邊我就來詳細的分析為什麼php腳本執行超出設定時間會導致nginx回傳502。
先來佈景,讓問題重現:
nginx和php分別只啟動一個worker,方便追蹤。
php-fpm的request_terminate_timeout設定為3s。
測試腳本test.php
sleep(20); echo 'ok';
go go go:
#在瀏覽器存取www.v.com/test.php,3s後如期出現...404 ? ? ? what? ? ?
出師不利啊,趕緊看看nginx的設定檔
這個location設定是當發生5xx錯誤時跳到一個好看點的介面,但是我在/usr/share/nginx/html下並沒有50x.html這個檔案。所以搞了個404出來。這不是很影響我判斷問題的準確度?直接註解掉!再次訪問,等待3s,終於'正常'的介面出來了。
環境好了,下邊就上套路,按照web問題的排查套路走一遍,先看看錯誤日誌吧:
nginx:
報錯都是recv() failed (104: connection reset by peer。
recv時失敗了,連接被重置了。為啥連接被重置了?難道一言不合。
我們在看看php-fpm的錯誤日誌:
(注意php-fpm中php_admin_value[error_log]選項指定php的錯誤日誌,會覆寫php.ini中的。但這裡不是看php的錯誤,而是看php-fpm的錯誤。php-fpm的錯誤日誌由php-fpm.conf中的error_log選項指定。)
每一次請求都是產生2個warning和1個notice:
warning:腳本執行逾時了,終止了。
warning:子程序收到sigterm訊號退出了。
notice:啟動了一個新的子進程(因為我設定的pm.min_spare_servers = 1)
看來如果php的worker進程執行逾時,不僅終止腳本執行,而且worker進程也會退出。看來nginx的報錯連接被重置是因為php的worker進程退出了(在tcp連接中一方如果斷掉的話會發送rst給另一方)
通過日誌已經可以知道php腳本執行逾時,worker子程序退出,導致nginx報錯connection reset by peer,下邊我們透過strace來看看php和nginx的狀況:
php:
1.accept一個nginx的連接請求(socket,bind,listen都在master中完成),可以看到nginx的連接埠是47039,從fd0讀取數據,就是從標準輸入中,這個是fast-cgi協定規定的。accept之後的已連接描述符是3。
2.從fd3讀取nginx傳遞過來的數據,fastcgi協定格式,接收了856位元組。為什麼read5次呢?
因為fastcgi協定封包是8位元組對齊,由包頭和包體組成。而且都是會先發一個request封包,包含一些請求id,版本,typpe等資訊(包頭包體各佔8位元組),再發一個params封包,傳遞get參數和環境變數(包頭8位元組,包體變長),最後發送一個沒有包體只有包頭的params資料包,表示參數發送結束(包頭8位元組)。所以前3個read用來讀出request包的包頭和包體,還有params包的包頭,第四個read是讀取真正的數據,最後一個read是讀取最後一個params包的包頭。所以nginx傳遞的資料應該是8 8 8 856 8=896位元組(和下邊nginx的傳輸bytes能對應上)。注意如果是post方式,也會傳送stdin封包。
3.設定休眠20s,就是php程式中的sleep(20),之後因為行程終止了,所以後邊就沒囉。 strace程式也退出啦。
nginx:
1.accept到瀏覽器的請求,可以看到瀏覽器端的連接埠是56434,ip是192.168.1.105,已建立連接的fd是3。
2.從fd3接收數據,http協定。
3.建立一個socket,fd21,用於和php建立連線。
4.連接到fd21,可以看到連接的是本機的9000端口,這裡nginx和php-fpm使用ip socket連接方式,nginx和php-fpm部署在一台機器上可以考慮unix domain socket。
5.寫入fd21資料,fast-cgi協定格式,我們看到寫入的長度是896,和上邊的php接收的長度是對應的。
6.recvfrom函數從fd21傳回 econnreset (connection reset by peer)
7.向fd9中寫入錯誤訊息,可以推斷fd9就是nginx錯誤日誌的檔案描述子。
8.關閉和fd21的連線。
9.寫入fd3502 bad gateway,就是傳回瀏覽器的資訊。
10.向fd8寫入一條存取日誌,可以推論fd8就是nginx存取日誌的檔案描述子。
來驗證一下nginx存取日誌和錯誤日誌的推論。可以看到的確是fd8,fd9,並處於寫入模式。
那麼在這個過程中整個網路包的傳輸我們不妨也看一下:
透過tcpdump抓包,用神器看比較方便。
因為只想看nginx和php的通訊,在上邊又知道nginx的連接埠是47039,可以透過tcp.srcport==47039過濾出對應的套件。
可以看到nginx和php-fpm資料互動的過程:47039->9000建立三次握手,接著向9000發送數據,9000回覆ack,3s後9000回覆rst。沒毛病。
注意:
syn,fin各佔一個序號
ack,rst不佔序號(28,29兩個套件的reqnum和acknum都是相同的)
序號是每一位元組加1(29包發送896字節,同時29包seq為4219146879,30包的ack為4219147775,正好相差896)
rst不需要回覆。
以上是nginx+php-fpm服務HTTP狀態碼502怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP在數據庫操作和服務器端邏輯處理中使用MySQLi和PDO擴展進行數據庫交互,並通過會話管理等功能處理服務器端邏輯。 1)使用MySQLi或PDO連接數據庫,執行SQL查詢。 2)通過會話管理等功能處理HTTP請求和用戶狀態。 3)使用事務確保數據庫操作的原子性。 4)防止SQL注入,使用異常處理和關閉連接來調試。 5)通過索引和緩存優化性能,編寫可讀性高的代碼並進行錯誤處理。

確認 Nginx 是否啟動的方法:1. 使用命令行:systemctl status nginx(Linux/Unix)、netstat -ano | findstr 80(Windows);2. 檢查端口 80 是否開放;3. 查看系統日誌中 Nginx 啟動消息;4. 使用第三方工具,如 Nagios、Zabbix、Icinga。

在 Linux 中啟動 Nginx 的步驟:檢查 Nginx 是否已安裝。使用 systemctl start nginx 啟動 Nginx 服務。使用 systemctl enable nginx 啟用在系統啟動時自動啟動 Nginx。使用 systemctl status nginx 驗證啟動是否成功。在 Web 瀏覽器中訪問 http://localhost 查看默認歡迎頁面。

在 Linux 中,使用以下命令檢查 Nginx 是否已啟動:systemctl status nginx根據命令輸出進行判斷:如果顯示 "Active: active (running)",則 Nginx 已啟動。如果顯示 "Active: inactive (dead)",則 Nginx 已停止。

如何在 Windows 中配置 Nginx?安裝 Nginx 並創建虛擬主機配置。修改主配置文件並包含虛擬主機配置。啟動或重新加載 Nginx。測試配置並查看網站。選擇性啟用 SSL 並配置 SSL 證書。選擇性設置防火牆允許 80 和 443 端口流量。

PHP用於構建動態網站,其核心功能包括:1.生成動態內容,通過與數據庫對接實時生成網頁;2.處理用戶交互和表單提交,驗證輸入並響應操作;3.管理會話和用戶認證,提供個性化體驗;4.優化性能和遵循最佳實踐,提升網站效率和安全性。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

如何解決 Nginx 403 Forbidden 錯誤?檢查文件或目錄權限;2. 檢查 .htaccess 文件;3. 檢查 Nginx 配置文件;4. 重啟 Nginx。其他可能原因還包括防火牆規則、SELinux 設置或應用程序問題。
