Nginx API 網關配置從零到可用的五個關鍵步驟
Nginx API 網關配置從零到可用的五個關鍵步驟
很多團隊在搭建微服務架構時,都會把 Nginx 選為 API 網關的第一站。原因很簡單:它輕量、穩定、生態成熟,幾乎每臺 Linux 服務器上都自帶。但真正動手配置時,不少人會發現,照著網上教程抄一遍,服務卻總是不通,要么路由轉發失敗,要么跨域報錯,要么上游服務收不到真實客戶端 IP。這些問題往往不是 Nginx 本身難用,而是對 API 網關的配置邏輯缺少系統理解。下面從實際搭建流程出發,拆解 Nginx 作為 API 網關時必須做好的五個環節。
理解反向代理與路由轉發的基本結構
API 網關最核心的能力就是反向代理。Nginx 通過 location 指令匹配請求路徑,再通過 proxy_pass 將請求轉發到后端服務。這一步看似簡單,但有兩個容易踩坑的地方。一是 proxy_pass 后面是否帶斜杠,行為完全不同。帶斜杠時,Nginx 會去掉 location 中匹配的部分再轉發;不帶斜杠時,則會把完整路徑原樣傳遞。比如 location /api/ 和 proxy_pass http://backend/,請求 /api/user 會被轉發為 /user,而如果 proxy_pass 不帶斜杠,則轉發為 /api/user。二是 upstream 塊的配置,建議用 upstream 定義后端服務器組,而不是直接在 proxy_pass 里寫 IP,這樣后續做負載均衡或健康檢查時只需修改一處。
配置請求頭傳遞與客戶端真實 IP 保留
網關作為中間層,必須把客戶端的原始信息透傳給后端。默認情況下,Nginx 轉發請求時,X-Real-IP 和 X-Forwarded-For 這些頭不會自動設置。如果后端服務依賴客戶端 IP 做日志、限流或地理位置判斷,就會拿到錯誤的網關內網地址。正確的做法是在 location 或 http 塊中加入 proxy_set_header 指令,將 $remote_addr 賦值給 X-Real-IP,并將原有的 X-Forwarded-For 追加當前 IP。同時別忘了設置 proxy_set_header Host $host,保證后端能正確識別請求的原始域名。對于使用 HTTPS 的場景,還要考慮 X-Forwarded-Proto,否則后端可能誤判協議類型,導致重定向地址變成 HTTP。
實現限流與安全防護的基本配置
API 網關的另一項重要職責是保護后端服務不被突發流量沖垮。Nginx 自帶的 ngx_http_limit_req_module 和 ngx_http_limit_conn_module 就能勝任大部分限流需求。配置時先定義限流區域,比如 limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s,然后在需要限流的 location 中引用 limit_req zone=api_limit burst=20 nodelay。這里的 burst 參數允許短時間內的突發請求,nodelay 則讓這些請求立即處理而不是排隊。對于安全層面,可以配合 allow 和 deny 指令做 IP 白名單,或者用 map 模塊根據 User-Agent 過濾爬蟲。但要注意,Nginx 的限流是基于共享內存的,zone 的大小要估算好,避免內存溢出導致 worker 進程崩潰。
跨域與 HTTPS 卸載的常見處理方式
前后端分離架構下,跨域問題是 API 網關必須解決的。Nginx 通過 add_header 指令添加 CORS 頭,但很多人只加了 Access-Control-Allow-Origin,忽略了預檢請求的處理。瀏覽器在發送復雜請求前會先發一個 OPTIONS 請求,如果網關沒有正確響應,前端就會報跨域錯誤。正確的做法是在 location 中單獨處理 OPTIONS 方法,返回 204 狀態碼,并帶上 Allow-Methods、Allow-Headers 等頭。另外,HTTPS 卸載也是網關的常見角色。在 Nginx 上配置 SSL 證書后,后端服務可以只監聽 HTTP,減輕證書管理的負擔。但要注意,卸載后后端收到的請求是 HTTP 的,如果后端有強制 HTTPS 跳轉的邏輯,需要關閉或調整,否則會產生重定向循環。
日志格式與調試技巧讓問題無處藏身
配置完成后,驗證和調試是必不可少的一步。很多人只靠瀏覽器看返回狀態碼,遇到 502 或 504 就無從下手。Nginx 的日志系統其實非常強大。先在 http 塊中定義一個詳細的 log_format,包含 $upstream_addr、$upstream_status、$upstream_response_time 等變量,然后在 server 或 location 中引用。這樣當請求出錯時,日志里就能看到請求被轉發到了哪個后端、后端返回了什么狀態碼、響應耗時多少。如果后端返回 502,通常意味著上游服務未啟動或端口不對;如果返回 504,則可能是后端處理超時,需要調整 proxy_read_timeout。另外,可以臨時在 location 中加入 error_page 指令,將 502 頁面替換為一段包含調試信息的 JSON 響應,方便快速定位問題。