Nginx 反向代理設定教學:從零開始搞懂負載均衡
說真的,我第一次接觸 Nginx 反向代理的時候,被那堆設定檔搞得一頭霧水。但用了幾年下來,我可以很負責任地說:Nginx 是目前最值得學的 web server 之一。今天這篇文章,我會用最白話的方式帶你從零開始設定反向代理和負載均衡。
什麼是反向代理?為什麼你需要它?
簡單來說,反向代理就是站在你的應用伺服器前面的一個「門衛」。用戶的請求先到 Nginx,Nginx 再轉發給後端的應用程式。這樣做有幾個好處:
- 隱藏後端伺服器的真實 IP 和架構
- 統一處理 SSL 加密,後端不用管憑證的事
- 可以做負載均衡,把流量分散到多台伺服器
- 靜態檔案快取,減輕後端壓力
如果你的專案已經用 Docker Compose 部署教學 中的方式把服務容器化了,那加上 Nginx 反向代理基本上是標配。
安裝 Nginx 與基本設定
在 Ubuntu 上安裝非常簡單:
sudo apt update
sudo apt install nginx
sudo systemctl start nginx
sudo systemctl enable nginx安裝完之後,打開瀏覽器輸入伺服器 IP,看到 Nginx 的歡迎頁面就代表成功了。接下來我們要修改設定檔,通常在 /etc/nginx/nginx.conf 或 /etc/nginx/sites-available/ 底下。
反向代理基本設定
假設你的 Node.js 應用跑在 port 3000,最基本的反向代理長這樣:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}這裡有個很容易忽略的細節:proxy_set_header 那幾行千萬別省略。少了它們,你的後端拿不到用戶的真實 IP,日誌全部變成 127.0.0.1,debug 的時候會很痛苦。我之前就踩過這個坑。
用 upstream 實現負載均衡
當你的應用開始有流量了,一台伺服器撐不住怎麼辦?這時候就需要負載均衡。Nginx 的 upstream 區塊可以定義一組後端伺服器:
upstream backend_servers {
server 192.168.1.101:3000 weight=3;
server 192.168.1.102:3000 weight=2;
server 192.168.1.103:3000 weight=1;
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}上面的 weight 參數代表權重,數字越大分到的流量越多。除了加權輪詢,Nginx 還支援幾種負載均衡策略:
- round-robin(預設):依序分配,最簡單
- least_conn:把請求送到連線數最少的伺服器
- ip_hash:同一個 IP 的用戶永遠送到同一台,適合有 session 的應用
- random:隨機分配,配合 two choices 效果不錯
我個人最常用的是 least_conn,因為它在伺服器效能不一致的情況下表現最穩定。如果你的 API 架構還在猶豫要用哪種風格,可以參考 GraphQL vs REST 比較 這篇文章。
健康檢查設定
負載均衡最怕的就是把流量送到已經掛掉的伺服器。Nginx 的被動健康檢查可以這樣設:
upstream backend_servers {
server 192.168.1.101:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.102:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.103:3000 backup;
}max_fails=3 表示連續失敗 3 次就暫時把這台標記為不可用,fail_timeout=30s 是冷卻時間,30 秒後再試。最後那台標記 backup 的伺服器只有在其他都掛掉時才會啟用,算是最後一道防線。
老實說,Nginx 開源版的健康檢查功能比較陽春。如果你需要主動式健康檢查(定期打 health endpoint),要嘛用 Nginx Plus,要嘛搭配外部工具來做。
SSL 終止設定
現在沒有 HTTPS 的網站基本上等於不存在。讓 Nginx 來處理 SSL 是最常見的做法,後端伺服器就不用各自管理憑證了:
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
}
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}底下那個 server 區塊是把所有 HTTP 流量 301 轉到 HTTPS。用 Let's Encrypt 搭配 Certbot 可以免費取得憑證,而且自動續期,非常方便。
效能調校小技巧
分享幾個我實際在用的設定,對效能提升蠻有感的:
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
gzip on;
gzip_types text/plain application/json application/javascript text/css;
gzip_min_length 1000;
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=1g;
location / {
proxy_cache my_cache;
proxy_cache_valid 200 10m;
proxy_pass http://backend_servers;
}如果你的應用有大量讀取操作,搭配 Redis 快取策略 效果會更好。Nginx 快取處理靜態資源,Redis 處理動態資料查詢,兩層快取下來速度會有質的飛躍。
常見踩坑與排錯
最後整理幾個我自己和同事常遇到的問題:
- 502 Bad Gateway:通常是後端服務沒啟動,或 proxy_pass 的 port 寫錯
- WebSocket 連線失敗:需要額外加
proxy_http_version 1.1和Upgradeheader - 上傳大檔案失敗:調整
client_max_body_size,預設只有 1MB - 設定改了沒生效:記得
nginx -t測試語法後再nginx -s reload
學會 Nginx 反向代理和負載均衡,基本上就打通了部署的任督二脈。從小型個人專案到中大型商業應用,這套技能都用得上。建議找一台測試機實際操作一遍,光看文件真的記不住。
繼續閱讀
Kubernetes K8s 入門完整教學:從 Pod 到部署微服務應用的完整指南
Kubernetes(K8s)是現代雲端部署的標準工具,但入門曲線陡峭讓很多工程師望而卻步。本文從最基本的概念開始,用清楚的類比解釋 Pod、Service、Deployment 的關係,再帶你一步一步部署一個包含前端、後端和資料庫的微服務應用,讓你真正理解 K8s 的威力。
相關文章
Kubernetes K8s 入門完整教學:從 Pod 到部署微服務應用的完整指南
Kubernetes(K8s)是現代雲端部署的標準工具,但入門曲線陡峭讓很多工程師望而卻步。本文從最基本的概念開始,用清楚的類比解釋 Pod、Service、Deployment 的關係,再帶你一步一步部署一個包含前端、後端和資料庫的微服務應用,讓你真正理解 K8s 的威力。
Docker Compose 多容器部署教學:從入門到實戰
完整 Docker Compose 多容器部署教學,涵蓋服務定義、networks、volumes 與 health checks 最佳實踐。立即學習容器化部署!
你可能也喜歡
探索其他領域的精選好文