web開發常見問題解決方案大全:502/503 Bad Gateway/Connection reset/504 timed out/400 Bad Request/401 Unauthorized/403 Forbidden
在使用反向代理(如 Nginx、HAProxy)或正向代理(如 Squid、Charles)時,經常會遇到各種 HTTP 錯誤碼。本文將圍繞以下幾類常見問題,逐一分析成因并給出排查及解決思路:
- 502 Bad Gateway/503 Service Unavailable
- Connection reset/Connection timed out
- 504 Gateway Timeout
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
目錄
- 502 Bad Gateway/503 Service Unavailable
- Connection reset/Connection timed out
- 504 Gateway Timeout
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
- 最佳實踐與監控建議
502 Bad Gateway/503 Service Unavailable
問題表現
- 代理或網關返回 HTTP 502 或 503,前端收到類似:
HTTP/1.1 502 Bad Gateway HTTP/1.1 503 Service Unavailable
根本成因
- 隧道建立失敗:代理服務器拒絕為你建立隧道(CONNECT),導致無法轉發請求到后端。
- 上游服務異常:后端應用進程掛死、重啟中或者服務不可達。
- 資源過載:后端承載過大,無法及時響應。
排查與解決
- 檢查隧道配置
- 對于 HTTPS 請求,代理必須支持
CONNECT
方法。 - 在 Nginx 中確認有
proxy_connect
與proxy_pass
配置,并開啟ssl_preread
(TCP 代理)或正確的ssl
配置。
- 對于 HTTPS 請求,代理必須支持
- 查看代理日志
- Nginx:
error_log /var/log/nginx/error.log notice;
- Squid:
cache.log
中查找拒絕隧道或連接錯誤。
- Nginx:
- 驗證后端連通性
curl -v -x http://proxy:port https://your-upstream.example.com
- 若此處就報 502/503,則說明代理與后端鏈路已斷。
- 重啟/擴容后端
- 確保后端進程健康;必要時水平擴容或加入健康檢查(health check)。
- 限流與熔斷
- 對高并發場景,可在代理層或服務層加限流,避免短時流量沖垮上游。
Connection reset/Connection timed out
問題表現
- 客戶端拋出
ECONNRESET
(Connection reset)或ETIMEDOUT
(Connection timed out)。 - 日志中看到:
Error: socket hang up Error: connect ETIMEDOUT
根本成因
- 代理卡死:代理線程/進程死鎖或資源耗盡,無法處理新的連接。
- 不支持隧道:代理根本沒實現 CONNECT 隧道功能,直接丟棄或關閉連接。
排查與解決
- 測試代理隧道能力
curl -v -x http://proxy:port https://example.com
- 若在
CONNECT proxy:port HTTP/1.1
后就重置,說明代理不支持隧道。
- 若在
- 檢查代理進程狀態
- 用
ps aux
、top
觀察 CPU/內存、線程數。 - 查看是否達到最大連接數限制(如 Nginx 的
worker_connections
、Squid 的max_filedescriptors
)。
- 用
- 替換或升級代理軟件
- 使用支持隧道的版本,或切換到成熟方案(如 TinyProxy、HAProxy)。
- 網絡與防火墻
- 確保代理服務器對外端口開放,無防火墻規則丟包。
- 檢查客戶端與代理之間的網絡鏈路。
504 Gateway Timeout
問題表現
- 前端或客戶端收到:
通常表示代理等待上游響應超過設定閾值。HTTP/1.1 504 Gateway Timeout
根本成因
- 上游響應慢:后端接口處理耗時超出代理超時設置。
- 網絡抖動:中間網絡鏈路不穩定,導致延遲飆升。
排查與解決
- 調整代理超時
- Nginx 示例:
proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s;
- HAProxy 示例:
timeout connect 10s timeout server 30s timeout client 30s
- Nginx 示例:
- 優化后端性能
- 數據庫索引、緩存(Redis/Memcached)、異步隊列。
- 分析慢查詢、CPU 瓶頸、垃圾回收等。
- 異步或批處理
- 對于超時敏感操作,可采用異步處理,前端快速返回,再由后臺通知。
- 多活與降級
- 在高延遲場景下,用本地緩存或降級邏輯保證用戶體驗。
400 Bad Request
問題表現
- 代理返回
HTTP/1.1 400 Bad Request
,并提示:“代理根本不認你的 CONNECT 請求。”
根本成因
- 請求格式錯誤:CONNECT 方法格式不符合 HTTP/1.1 規范。
- 代理不支持 CONNECT:僅允許 GET/POST 等“簡單”方法。
排查與解決
- 確認請求格式
- 正確的 CONNECT 用法:
CONNECT api.example.com:443 HTTP/1.1 Host: api.example.com:443 Proxy-Authorization: Basic XXXXX
- 正確的 CONNECT 用法:
- 檢查代理白名單
- Squid 中需在配置里加:
acl SSL_ports port 443 http_access allow CONNECT SSL_ports
- Squid 中需在配置里加:
- 升級或更換代理
- 如老版本 Squid(??.0)可能不完全支持 TLS 隧道。
- 使用 HTTPS 直連
- 若業務允許,可繞過代理直連后端,或使用更現代的 HTTP/2 直連方案。
401 Unauthorized
問題表現
- 客戶端或瀏覽器收到:
或響應頭中帶有HTTP/1.1 401 Unauthorized
WWW-Authenticate
。
根本成因
- 認證憑證缺失或無效:請求未包含或包含錯誤的
Authorization
頭。 - Token 過期或簽名錯誤:JWT、OAuth2 Token 已過期或無效。
- 跨域預檢失敗:CORS 預檢請求未攜帶合法認證信息。
排查與解決
- 檢查 Authorization 頭
- 確認格式為:
Authorization: Bearer <token>
或Basic <credentials>
。
- 確認格式為:
- 驗證 Token 有效性
- 解碼 JWT,檢查
exp
、nbf
等字段。 - 與認證服務同步時間,確保無時差。
- 解碼 JWT,檢查
- 查看認證服務日志
- 檢查認證服務器(如 Keycloak、Auth0)返回的錯誤詳情。
- 配置 CORS
- 在代理或應用中允許跨域
Authorization
頭:add_header Access-Control-Allow-Headers "Authorization,Content-Type";
- 在代理或應用中允許跨域
- 重試或刷新憑證
- 對于過期 Token,可設計自動刷新機制。
403 Forbidden
問題表現
- 客戶端收到:
無論請求格式和認證憑證是否正確,仍提示權限不足。HTTP/1.1 403 Forbidden
根本成因
- 訪問權限不足:用戶或客戶端沒有訪問該資源的權限。
- ACL 配置錯誤:代理或應用層的訪問控制列表設置不當。
- CSRF 驗證失敗:請求未帶或帶錯 CSRF Token。
排查與解決
- 檢查用戶角色與權限
- 后端或 IAM 系統查看用戶是否在允許訪問列表。
- 驗證訪問控制配置
- Nginx 示例:
location /admin {allow 192.168.1.0/24;deny all; }
- Nginx 示例:
- 檢查 CSRF 配置
- 確保表單或 AJAX 請求攜帶合法的 CSRF Token。
- 文件/目錄權限
- 對靜態資源,檢查文件系統權限(Linux 下
chmod
/chown
)。
- 對靜態資源,檢查文件系統權限(Linux 下
- 日志與審計
- 在代理和應用層啟用審計日志,定位拒絕原因。
最佳實踐與監控建議
- 完善日志與告警
- 在代理層與應用層分別配置日志,并接入 ELK/Prometheus+Grafana。
- 健康檢查與自動化重試
- 針對常見超時和網絡抖動,自動重試或流量切換。
- 容量規劃與限流
- 根據業務增長定期評估代理與后端承載能力。
- 文檔與規范
- 團隊內統一請求格式、代理使用規范,并做好培訓。
通過以上完善的錯誤碼排查與解決方案,基本涵蓋了代理相關的常見4xx/5xx問題。從日志入手,找到根因,結合代理和后端配置,才能在復雜網絡環境和高并發場景下保障服務穩定運行。