http 500内部服务器错误排查及修复指南

深夜收到服務器告警郵件時,最怕看到的就是那行「HTTP 500 Internal Server Error」。這種泛用性錯誤就像蒙著眼的捉迷藏,伺服器只告訴你「我壞了」,卻不說明哪裡壞了。這些年處理過的500錯誤沒上千也有幾百次,分享些實戰中磨出來的排查思路。

第一步永遠是登入伺服器看日誌,但多數人只盯著access.log。真正有金礦的是error.log,尤其是配合時間戳精準定位。上週幫電商客戶排查時,發現他們的Nginx配置把PHP錯誤全吞了,緊急加了fastcgi_intercept_errors on;才看到致命錯誤:「Allowed memory size exhausted」。原來是某個新上線的促銷插件狂吃512MB記憶體。

資料庫連線崩潰是隱形殺手。有次跨年夜流量高峰,某票務平台出現間歇性500錯誤。表面看API服務正常,最後在MySQL慢查詢日誌揪出元兇:某個未加索引的座位狀態檢查語句,單次執行竟耗費2.3秒,連接池直接被撐爆。臨時用SHOW FULL PROCESSLIST鎖定問題查詢,緊急添加索引才穩住系統。

別忽略第三方服務的雪崩效應。幫跨境支付平台做健檢時,發現他們每筆交易都同步調用風控API。當外部服務響應延遲時,自家伺服器執行緒全卡死在等待中。後來改成非同步佇列處理,並在代碼層增加熔斷機制,錯誤率從15%驟降到0.2%。

伺服器資源枯竭往往偽裝成500錯誤。曾有個客戶的Node.js服務每天凌晨崩潰,top命令看不出異常。直到用pm2 logs拉出歷史紀錄,才發現定時任務觸發的記憶體洩漏——一段遞迴函數未設終止條件。用heapdump抓取記憶體快照後,在Chrome DevTools裡看到閉包變數像滾雪球般增長。

文件權限問題在協作環境特別致命。記得某團隊上傳圖片功能突然失效,日誌顯示「Permission denied」。原來運維更新伺服器時重置了/var/www/uploads所有者,PHP進程失去寫入權限。用namei -l /path/to/file逐層檢查權限鏈才發現癥結。

臨時修復後,一定要在預發布環境重現故障。推薦用strace -p 進程ID追蹤系統呼叫,比埋日誌更高效。有次追查Laravel框架的500錯誤,就是透過strace發現它卡在嘗試讀取已被刪除的.env檔案。

最痛的一次教訓是誤操作:客戶工程師手動清理Redis時執行了FLUSHALL,導致全站工作階段丟失。現在我總在備忘錄置頂寫著:動生產環境前,先確認連的是不是測試集群。

當你以為修復完畢,用瀏覽器測試前務必強制刷新(Ctrl+F5)。很多時候瀏覽器快取了500錯誤頁面,讓人誤以為問題仍在。這小動作省過我不少白工。

最後的保命建議:每次修改前用tar -zcvf backup_$(date +%F).tar.gz /etc/nginx /path/to/code打個快照。有回誤刪nginx.conf裡的監聽端口,靠這招三分鐘回血。500錯誤不可怕,可怕的是排查時的手忙腳亂。

評論:

  • 求問怎麼區分502和500?我們服務經常交替出現這兩個錯誤,快被搞瘋了
  • 實測strace神器!昨天靠它抓到一個文件描述符洩漏問題,開發組死活不信是他們代碼問題
  • 資料庫那段深有同感,我們用MongoDB也遇過類似狀況,連接池爆掉時連錯誤日誌都寫不進去
  • 第三方服務超時設定太關鍵了,最近剛把外部API調用超時從預設30秒改成3秒,錯誤率直接腰斬
  • 權限檢查那招namei命令馬上筆記,之前每次都是手動一層層ls -l檢查快累死
  • Leave a comment

    您的邮箱地址不会被公开。 必填项已用 * 标注