国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Nginx反向代理和負載均衡配置實戰(zhàn)

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 2026-01-23 13:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Nginx反向代理+負載均衡實戰(zhàn):小白也能搭建高可用架構(gòu)

一、概述

1.1 背景介紹

2023年我?guī)Я藗€新人,讓他搭個負載均衡,結(jié)果他配了半天,流量全跑到一臺機器上,另外兩臺閑著。排查了一個小時,發(fā)現(xiàn)他把upstream里的server全寫成了localhost。這事兒讓我意識到,反向代理和負載均衡看著簡單,坑還真不少。

對于很多剛?cè)胄械耐瑢W(xué)來說,"反向代理"這詞聽著就讓人頭大。其實沒那么復(fù)雜:正向代理是代理客戶端(比如VPN),反向代理是代理服務(wù)端。用戶訪問的是Nginx,Nginx再去訪問真正的后端服務(wù),用戶根本不知道后端服務(wù)的存在。

負載均衡則是反向代理的進階玩法。當(dāng)一臺后端服務(wù)器扛不住流量的時候,就需要多臺服務(wù)器一起分擔(dān)壓力。Nginx負責(zé)把請求分發(fā)到不同的服務(wù)器上,這就是負載均衡。

1.2 技術(shù)特點

反向代理的價值

隱藏后端服務(wù)器真實IP,增強安全性

統(tǒng)一入口,便于管理和監(jiān)控

SSL卸載,減輕后端壓力

靜態(tài)資源緩存,減少后端請求

請求過濾和限流

負載均衡的價值

水平擴展,突破單機性能瓶頸

高可用,單點故障不影響服務(wù)

靈活調(diào)度,支持多種算法

灰度發(fā)布,逐步遷移流量

1.3 適用場景

Web應(yīng)用集群部署

API網(wǎng)關(guān)入口

微服務(wù)架構(gòu)流量分發(fā)

靜態(tài)資源與動態(tài)請求分離

多數(shù)據(jù)中心流量調(diào)度

藍綠部署和灰度發(fā)布

1.4 環(huán)境要求

組件 版本 說明
操作系統(tǒng) Rocky Linux 9.4 / Ubuntu 24.04 LTS 穩(wěn)定的生產(chǎn)環(huán)境系統(tǒng)
Nginx 1.26.2 建議使用stable分支
后端服務(wù) 任意HTTP服務(wù) 示例用Tomcat 10.1.x
網(wǎng)絡(luò) 內(nèi)網(wǎng)互通 Nginx與后端服務(wù)器網(wǎng)絡(luò)延遲<1ms

實驗環(huán)境架構(gòu)

          ┌─────────────────┐
          │  Client請求  │
          └────────┬────────┘
              │
              ▼
          ┌─────────────────┐
          │ Nginx負載均衡  │
          │ 192.168.1.10  │
          └────────┬────────┘
              │
     ┌─────────────────┼─────────────────┐
     │         │         │
     ▼         ▼         ▼
  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
  │ Backend 1 │  │ Backend 2 │  │ Backend 3 │
  │ 192.168.1.11│  │ 192.168.1.12│  │ 192.168.1.13│
  └─────────────┘  └─────────────┘  └─────────────┘

二、詳細步驟

2.1 準(zhǔn)備工作

2.1.1 安裝Nginx

Rocky Linux 9

# 添加Nginx官方倉庫
cat > /etc/yum.repos.d/nginx.repo <

Ubuntu 24.04

# 安裝依賴
apt update
apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y

# 添加Nginx官方GPG密鑰
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor 
  | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# 添加倉庫
echo"deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] 
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx"
  | tee /etc/apt/sources.list.d/nginx.list

# 安裝
apt update
apt install nginx -y

# 啟動
systemctl start nginx
systemctlenablenginx

2.1.2 準(zhǔn)備后端服務(wù)

這里用一個簡單的Python HTTP服務(wù)來模擬后端,方便看到請求分發(fā)到了哪臺機器:

#!/usr/bin/env python3
# backend_server.py
importhttp.server
importsocketserver
importsocket

PORT =8080
HOSTNAME = socket.gethostname()
IP = socket.gethostbyname(HOSTNAME)

classMyHandler(http.server.SimpleHTTPRequestHandler):
 defdo_GET(self):
    self.send_response(200)
    self.send_header('Content-type','text/html')
    self.end_headers()
    response =f"""
    
    
    

Hello from Backend Server

Hostname:{HOSTNAME}

IP:{IP}

Port:{PORT}

Request Path:{self.path}

""" self.wfile.write(response.encode()) withsocketserver.TCPServer(("", PORT), MyHandler)ashttpd: print(f"Serving on port{PORT}") httpd.serve_forever()

在三臺后端服務(wù)器上分別啟動:

python3 backend_server.py

或者如果你有Tomcat環(huán)境,直接用Tomcat也行:

# 修改不同服務(wù)器的端口,便于區(qū)分
# server.xml中修改HTTP Connector端口
# 分別啟動三臺Tomcat

2.2 核心配置

2.2.1 最簡單的反向代理

先從最簡單的配置開始,讓Nginx把請求轉(zhuǎn)發(fā)到后端服務(wù):

# /etc/nginx/conf.d/proxy.conf
server {
  listen 80;
  server_name example.com;

  location / {
    proxy_pass http://192.168.1.11:8080;
  }
}

測試一下:

curl http://192.168.1.10

你會看到返回的是后端服務(wù)器的響應(yīng)。這就是最基礎(chǔ)的反向代理,就這么簡單。

2.2.2 完善的反向代理配置

實際生產(chǎn)中,光一個proxy_pass肯定不夠。下面是生產(chǎn)環(huán)境必須配置的參數(shù):

server {
  listen 80;
  server_name example.com;

  location / {
    proxy_pass http://192.168.1.11:8080;

    # 代理頭設(shè)置(重要!)
    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;

    # 超時設(shè)置
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;

    # 緩沖設(shè)置
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 32k;
    proxy_busy_buffers_size 64k;
  }
}

幾個關(guān)鍵配置解釋

proxy_set_header Host $host:把客戶端請求的Host頭傳給后端。不設(shè)置這個,后端收到的Host是upstream的地址,很多應(yīng)用會出問題。

X-Real-IP和X-Forwarded-For:讓后端知道真實的客戶端IP。不設(shè)置的話,后端看到的都是Nginx的IP。

proxy_buffering:開啟緩沖后,Nginx會先把后端響應(yīng)存到緩沖區(qū),再發(fā)給客戶端。這樣即使客戶端網(wǎng)速慢,也不會一直占用后端連接。

踩坑記錄:有次我們的后端應(yīng)用一直獲取不到客戶端真實IP,日志里全是Nginx的內(nèi)網(wǎng)IP。排查半天,發(fā)現(xiàn)是忘了配X-Forwarded-For頭。后端應(yīng)用也需要配置信任代理地址才能正確解析這個頭。

2.2.3 基礎(chǔ)負載均衡

現(xiàn)在來配置負載均衡,把請求分發(fā)到多臺后端服務(wù)器:

# /etc/nginx/conf.d/loadbalance.conf

# 定義后端服務(wù)器組
upstream backend_pool {
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;
}

server {
  listen 80;
  server_name example.com;

  location / {
    proxy_pass http://backend_pool;

    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;
  }
}

測試負載均衡效果:

# 連續(xù)發(fā)送多個請求,觀察響應(yīng)中的服務(wù)器IP變化
foriin{1..10};do
  curl -s http://192.168.1.10 | grep"IP:"
done

你會看到請求被輪流分發(fā)到三臺服務(wù)器上,這就是默認(rèn)的輪詢(Round Robin)算法。

2.2.4 負載均衡算法詳解

Nginx支持多種負載均衡算法,選擇合適的算法對系統(tǒng)性能影響很大。

1. 輪詢(Round Robin)- 默認(rèn)

upstream backend_pool {
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;
}

最簡單粗暴的算法,按順序把請求分給每臺服務(wù)器。適合后端服務(wù)器配置相同、無狀態(tài)服務(wù)的場景。

2. 加權(quán)輪詢(Weighted Round Robin)

upstream backend_pool {
  server 192.168.1.11:8080 weight=5; # 處理50%的請求
  server 192.168.1.12:8080 weight=3; # 處理30%的請求
  server 192.168.1.13:8080 weight=2; # 處理20%的請求
}

服務(wù)器配置不同時使用。比如有臺8核的機器和兩臺4核的,給8核的機器分配更多權(quán)重。

3. 最少連接數(shù)(Least Connections)

upstream backend_pool {
  least_conn;
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;
}

把請求分給當(dāng)前連接數(shù)最少的服務(wù)器。適合請求處理時間不均勻的場景,比如有些請求1秒就處理完,有些要10秒。

實戰(zhàn)經(jīng)驗:我們的API網(wǎng)關(guān)一開始用輪詢,后來發(fā)現(xiàn)有些慢接口會導(dǎo)致某臺服務(wù)器連接堆積。換成least_conn后,負載變得均勻多了。

4. IP哈希(IP Hash)

upstream backend_pool {
  ip_hash;
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;
}

根據(jù)客戶端IP的哈希值分配服務(wù)器,同一個IP的請求總是落到同一臺服務(wù)器。適合需要會話保持的場景。

注意:ip_hash有個坑,如果你前面還有一層代理(比如CDN),那所有請求的客戶端IP都是CDN的IP,ip_hash就失效了。這時候需要用$http_x_forwarded_for來取真實IP。

5. 一致性哈希(Hash)

upstream backend_pool {
  hash $request_uri consistent;
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;
}

根據(jù)指定的key進行哈希。consistent參數(shù)啟用一致性哈希,當(dāng)服務(wù)器增減時,只有少部分請求會重新映射。

常用的hash key:

$request_uri:相同URL總是落到同一臺服務(wù)器,適合緩存場景

$arg_userid:按用戶ID分流

$cookie_sessionid:按session分流

6. 隨機(Random)

upstream backend_pool {
  random two least_conn;
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;
}

隨機選擇兩臺服務(wù)器,然后從中選連接數(shù)少的那臺。這個算法在Nginx 1.15.1引入,據(jù)官方說在大規(guī)模集群中效果比least_conn更好。

2.2.5 健康檢查配置

負載均衡必須配合健康檢查,不然一臺服務(wù)器掛了,流量還往那兒發(fā),用戶體驗就很差了。

被動健康檢查(開源版Nginx):

upstream backend_pool {
  server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
  server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
  server 192.168.1.13:8080 max_fails=3 fail_timeout=30s;
}

參數(shù)說明:

max_fails=3:連續(xù)3次請求失敗就認(rèn)為服務(wù)器掛了

fail_timeout=30s:服務(wù)器被標(biāo)記為不可用的時間,30秒后會再次嘗試

問題:被動檢查有延遲,要等真實流量失敗才能發(fā)現(xiàn)問題。而且恢復(fù)后也是立即全量切入,可能導(dǎo)致瞬間壓力過大。

主動健康檢查(Nginx Plus或第三方模塊):

如果你用的是開源版Nginx,可以安裝nginx_upstream_check_module模塊:

upstream backend_pool {
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;

  # 主動健康檢查配置
  check interval=3000 rise=2 fall=3 timeout=2000 type=http;
  check_http_send "GET /health HTTP/1.0

";
  check_http_expect_alive http_2xx http_3xx;
}

server {
  # 健康檢查狀態(tài)頁面
  location /upstream_status {
    check_status;
    access_log off;
    allow 192.168.1.0/24;
    deny all;
  }
}

參數(shù)說明:

interval=3000:每3秒檢查一次

rise=2:連續(xù)2次成功認(rèn)為恢復(fù)

fall=3:連續(xù)3次失敗認(rèn)為宕機

type=http:使用HTTP檢查

2.2.6 后備服務(wù)器配置

upstream backend_pool {
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080 backup; # 備用服務(wù)器
  server 192.168.1.14:8080 down;  # 標(biāo)記為下線,不接收流量
}

backup:備用服務(wù)器,只有當(dāng)所有主服務(wù)器都不可用時才啟用

down:標(biāo)記服務(wù)器為下線狀態(tài),通常用于維護

2.2.7 連接復(fù)用配置

每次代理請求都新建TCP連接太浪費了,配置keepalive可以復(fù)用連接:

upstream backend_pool {
  server 192.168.1.11:8080;
  server 192.168.1.12:8080;
  server 192.168.1.13:8080;

  # 每個worker保持的空閑連接數(shù)
  keepalive 100;

  # 單個連接最大請求數(shù)
  keepalive_requests 1000;

  # 連接空閑超時
  keepalive_timeout 60s;
}

server {
  location / {
    proxy_pass http://backend_pool;

    # 必須!使用HTTP/1.1和清空Connection頭
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  }
}

這兩行配置很容易漏掉

proxy_http_version 1.1;
proxy_set_header Connection "";

不加這兩行,keepalive就不生效。因為HTTP/1.0默認(rèn)是短連接,而且Nginx默認(rèn)會把Connection頭設(shè)成close。

2.3 啟動和驗證

2.3.1 配置驗證

# 檢查配置語法
nginx -t

# 輸出示例
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

2.3.2 重載配置

# 平滑重載,不中斷服務(wù)
nginx -s reload

# 或者使用systemd
systemctl reload nginx

2.3.3 驗證負載均衡

# 方法1:多次curl觀察響應(yīng)
foriin{1..10};do
  curl -s http://192.168.1.10 | grep"IP:"
  sleep 0.5
done

# 方法2:使用ab壓測
ab -n 1000 -c 100 http://192.168.1.10/

# 方法3:查看后端服務(wù)器訪問日志
tail -f /var/log/nginx/access.log

三、示例代碼和配置

3.1 完整配置示例

這是一個生產(chǎn)級的反向代理+負載均衡配置:

# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;

error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
  worker_connections 65535;
  use epoll;
  multi_accept on;
}

http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  # 日志格式
  log_format main '$remote_addr - $remote_user [$time_local] "$request" '
          '$status $body_bytes_sent "$http_referer" '
          '"$http_user_agent" "$http_x_forwarded_for" '
          'rt=$request_time uct="$upstream_connect_time" '
          'uht="$upstream_header_time" urt="$upstream_response_time"';

  access_log /var/log/nginx/access.log main;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  keepalive_timeout 65;
  keepalive_requests 10000;

  # Gzip壓縮
  gzip on;
  gzip_vary on;
  gzip_min_length 1024;
  gzip_types text/plain text/css application/json application/javascript;

  # 上游服務(wù)器組
  upstream api_servers {
    least_conn;

    server 192.168.1.11:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.13:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.14:8080 backup;

    keepalive 300;
    keepalive_requests 10000;
    keepalive_timeout 60s;
  }

  # 靜態(tài)資源服務(wù)器組
  upstream static_servers {
    server 192.168.1.21:80;
    server 192.168.1.22:80;

    keepalive 100;
  }

  # 限流配置
  limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
  limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

  # 主站配置
  server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
  }

  server {
    listen 443 ssl;
    http2 on;
    server_name example.com www.example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_session_cache shared10m;
    ssl_session_timeout 1d;
    ssl_protocols TLSv1.2 TLSv1.3;

    # 安全頭
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # API接口
    location /api/ {
      limit_req zone=api_limit burst=50 nodelay;
      limit_conn conn_limit 20;

      proxy_pass http://api_servers;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      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_connect_timeout 10s;
      proxy_send_timeout 60s;
      proxy_read_timeout 60s;

      proxy_next_upstream error timeout http_502 http_503 http_504;
      proxy_next_upstream_tries 3;
      proxy_next_upstream_timeout 30s;
    }

    # 靜態(tài)資源
    location /static/ {
      proxy_pass http://static_servers;
      proxy_http_version 1.1;
      proxy_set_header Connection "";

      proxy_cache_valid 200 1d;
      expires 30d;
      add_header Cache-Control "public, immutable";
    }

    # WebSocket代理
    location /ws/ {
      proxy_pass http://api_servers;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_read_timeout 86400s;
    }

    # 健康檢查接口
    location /health {
      access_log off;
      return 200 'OK';
      add_header Content-Type text/plain;
    }
  }

  # 內(nèi)部狀態(tài)監(jiān)控
  server {
    listen 127.0.0.1:8080;

    location /nginx_status {
      stub_status on;
      access_log off;
    }
  }
}

3.2 實際應(yīng)用案例

案例1:電商網(wǎng)站高可用架構(gòu)

背景:日均PV 1000萬,需要支持大促期間10倍流量峰值

架構(gòu)設(shè)計:

            ┌─────────────────┐
            │   CDN層    │
            │ 靜態(tài)資源加速  │
            └────────┬────────┘
                 │
            ┌────────▼────────┐
            │  SLB/CLB層   │
            │ 云負載均衡器  │
            └────────┬────────┘
                 │
       ┌───────────────────┼───────────────────┐
       │          │          │
   ┌──────▼──────┐   ┌──────▼──────┐   ┌──────▼──────┐
   │ Nginx 01  │   │ Nginx 02  │   │ Nginx 03  │
   │ 反向代理集群 │   │ 反向代理集群 │   │ 反向代理集群 │
   └──────┬──────┘   └──────┬──────┘   └──────┬──────┘
       │          │          │
       └───────────────────┼───────────────────┘
                 │
   ┌──────────────────────────┼──────────────────────────┐
   │             │             │
   ▼             ▼             ▼
 ┌─────────┐       ┌─────────┐        ┌─────────┐
 │ API集群 │       │ Web集群 │        │ 靜態(tài)資源 │
 │ 商品/訂單│       │ 前端渲染 │        │ 圖片/CSS │
 └─────────┘       └─────────┘        └─────────┘

Nginx配置:

# 商品服務(wù)
upstream product_service {
  least_conn;
  server 10.0.1.1:8080 weight=3;
  server 10.0.1.2:8080 weight=3;
  server 10.0.1.3:8080 weight=2;
  keepalive 200;
}

# 訂單服務(wù)
upstream order_service {
  least_conn;
  server 10.0.2.1:8080 weight=3;
  server 10.0.2.2:8080 weight=3;
  server 10.0.2.3:8080 weight=2;
  keepalive 200;
}

# 用戶服務(wù)
upstream user_service {
  ip_hash; # 需要會話保持
  server 10.0.3.1:8080;
  server 10.0.3.2:8080;
  server 10.0.3.3:8080;
  keepalive 100;
}

server {
  listen 80;
  server_name api.shop.com;

  # 商品接口
  location /api/products {
    proxy_pass http://product_service;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    # ... 其他代理配置
  }

  # 訂單接口
  location /api/orders {
    proxy_pass http://order_service;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    # ... 其他代理配置
  }

  # 用戶接口
  location /api/users {
    proxy_pass http://user_service;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    # ... 其他代理配置
  }
}

案例2:灰度發(fā)布配置

背景:新版本上線,先讓10%的用戶訪問新版本,驗證沒問題后逐步擴大比例

# 新舊版本服務(wù)器
upstream app_v1 {
  server 10.0.1.1:8080;
  server 10.0.1.2:8080;
  keepalive 100;
}

upstream app_v2 {
  server 10.0.2.1:8080;
  server 10.0.2.2:8080;
  keepalive 100;
}

# 方法1:基于權(quán)重的灰度
upstream app_canary {
  server 10.0.1.1:8080 weight=9; # v1
  server 10.0.1.2:8080 weight=9; # v1
  server 10.0.2.1:8080 weight=1; # v2 (10%)
  server 10.0.2.2:8080 weight=1; # v2 (10%)
  keepalive 100;
}

# 方法2:基于Cookie的灰度
map $cookie_version $upstream_group {
  default app_v1;
  "v2"  app_v2;
}

# 方法3:基于請求頭的灰度
map $http_x_version $upstream_group_header {
  default app_v1;
  "v2"  app_v2;
}

# 方法4:基于用戶ID的灰度(取模)
split_clients $arg_userid $app_version {
  10% app_v2;
  *  app_v1;
}

server {
  listen 80;
  server_name app.example.com;

  # 使用Cookie灰度
  location / {
    proxy_pass http://$upstream_group;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  }

  # 設(shè)置灰度Cookie的接口
  location /set_version {
    add_header Set-Cookie "version=$arg_v; Path=/; Max-Age=86400";
    return 200 "Version set to $arg_v";
  }
}

灰度發(fā)布流程:

部署新版本服務(wù)到v2集群

配置10%流量到v2

監(jiān)控v2的錯誤率、響應(yīng)時間

逐步調(diào)整權(quán)重:10% -> 30% -> 50% -> 100%

下線v1集群

案例3:WebSocket負載均衡

背景:實時聊天應(yīng)用,需要長連接支持

upstream ws_servers {
  # WebSocket需要會話保持
  ip_hash;
  server 10.0.1.1:8080;
  server 10.0.1.2:8080;
  server 10.0.1.3:8080;

  # WebSocket連接數(shù)較少,keepalive可以小一些
  keepalive 50;
}

server {
  listen 80;
  server_name ws.example.com;

  location / {
    proxy_pass http://ws_servers;
    proxy_http_version 1.1;

    # WebSocket必須的頭
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # WebSocket長連接超時設(shè)置
    proxy_read_timeout 86400s;
    proxy_send_timeout 86400s;

    # 禁用緩沖
    proxy_buffering off;
  }
}

踩坑記錄:WebSocket一開始配了least_conn,結(jié)果用戶聊著聊著就斷線了。排查發(fā)現(xiàn)是連接被分到了不同的服務(wù)器。WebSocket必須用ip_hash或者sticky session保證會話保持。

四、最佳實踐和注意事項

4.1 最佳實踐

1. 分層部署架構(gòu)

不要把所有服務(wù)都放在一個upstream里,按業(yè)務(wù)功能分組:

# 好的做法
upstream user_api { ... }
upstream order_api { ... }
upstream product_api { ... }

# 不好的做法
upstream all_api {
  server user1:8080;
  server user2:8080;
  server order1:8080; # 混在一起
  server product1:8080; # 難以管理
}

2. 合理的超時設(shè)置

不同類型的請求設(shè)置不同的超時:

# 短請求(列表查詢)
location /api/list {
  proxy_read_timeout 10s;
}

# 長請求(報表導(dǎo)出)
location /api/export {
  proxy_read_timeout 300s;
}

# 文件上傳
location /api/upload {
  client_max_body_size 500m;
  proxy_read_timeout 600s;
}

3. 錯誤頁面友好展示

# 自定義錯誤頁面
error_page 502 503 504 /50x.html;
location = /50x.html {
  root /usr/share/nginx/html;
  internal;
}

# 或者返回JSON
error_page 502 503 504 = @fallback;
location @fallback {
  default_type application/json;
  return 503 '{"code": 503, "message": "Service temporarily unavailable"}';
}

4. 監(jiān)控指標(biāo)收集

日志中記錄upstream響應(yīng)時間,便于分析:

log_format upstream_log '$remote_addr [$time_local] '
  '$request $status '
  'upstream: $upstream_addr '
  'response_time: $upstream_response_time '
  'connect_time: $upstream_connect_time';

5. 平滑擴縮容

新增服務(wù)器時,先設(shè)置低權(quán)重,逐步提升:

upstream backend {
  server 10.0.1.1:8080 weight=10;
  server 10.0.1.2:8080 weight=10;
  server 10.0.1.3:8080 weight=1; # 新機器,先低權(quán)重
}

4.2 注意事項

常見錯誤 原因分析 解決方案
502 Bad Gateway 后端服務(wù)未啟動或連接被拒絕 檢查后端服務(wù)狀態(tài),確認(rèn)端口正確
504 Gateway Timeout 后端響應(yīng)超時 增加proxy_read_timeout,或優(yōu)化后端性能
upstream無法連接 網(wǎng)絡(luò)不通或防火墻阻止 檢查網(wǎng)絡(luò)連通性,開放防火墻端口
keepalive不生效 缺少必要配置 添加proxy_http_version 1.1和Connection ""
負載不均衡 算法選擇不當(dāng)或權(quán)重配置問題 根據(jù)場景選擇合適算法,檢查權(quán)重配置
會話丟失 無狀態(tài)輪詢導(dǎo)致請求分發(fā)到不同服務(wù)器 使用ip_hash或sticky session
健康檢查延遲 被動檢查需要真實流量觸發(fā) 配置主動健康檢查模塊
X-Forwarded-For鏈過長 多層代理重復(fù)追加 在入口處設(shè)置X-Forwarded-For為$remote_addr

五、故障排查和監(jiān)控

5.1 故障排查

5.1.1 常見故障診斷流程

502錯誤排查

# 1. 檢查后端服務(wù)是否運行
curl -I http://backend_ip:port/health

# 2. 檢查Nginx到后端的網(wǎng)絡(luò)連通性
telnet backend_ip port

# 3. 查看Nginx錯誤日志
tail -f /var/log/nginx/error.log

# 4. 檢查后端服務(wù)日志
# 看是否收到請求,是否有報錯

# 5. 檢查連接數(shù)是否達到限制
ss -s
cat /proc/sys/net/core/somaxconn

504超時排查

# 1. 測試后端接口響應(yīng)時間
time curl http://backend_ip:port/api/slow

# 2. 檢查Nginx超時配置
nginx -T | grep -E"proxy_.*_timeout"

# 3. 分析慢請求日志
awk'$NF > 5'/var/log/nginx/access.log # 響應(yīng)時間>5秒的請求

負載不均排查

# 1. 統(tǒng)計各后端服務(wù)器請求量
awk'{print $NF}'/var/log/nginx/access.log | sort | uniq -c | sort -rn

# 2. 檢查upstream配置
nginx -T | grep -A 20"upstream"

# 3. 檢查是否有服務(wù)器被標(biāo)記為不可用
# 查看error.log中的upstream相關(guān)錯誤

5.1.2 調(diào)試配置

臨時開啟詳細日志排查問題:

# 臨時配置,排查完記得關(guān)掉
error_log /var/log/nginx/error.log debug;

# 或者只對特定請求開啟debug
location /api/problem {
  error_log /var/log/nginx/debug.log debug;
  proxy_pass http://backend;
}

5.2 性能監(jiān)控

5.2.1 內(nèi)置狀態(tài)監(jiān)控

server {
  listen 127.0.0.1:8080;

  location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
  }
}

獲取狀態(tài):

curl http://127.0.0.1:8080/nginx_status

# 輸出示例:
# Active connections: 234
# server accepts handled requests
# 12847932 12847932 98234756
# Reading: 5 Writing: 67 Waiting: 162

指標(biāo)說明:

Active connections:當(dāng)前活躍連接數(shù)

accepts:已接受的連接總數(shù)

handled:已處理的連接總數(shù)(應(yīng)該等于accepts,不等說明有連接被丟棄)

requests:已處理的請求總數(shù)

Reading:正在讀取請求頭的連接數(shù)

Writing:正在發(fā)送響應(yīng)的連接數(shù)

Waiting:Keep-alive空閑連接數(shù)

5.2.2 Prometheus監(jiān)控集成

使用nginx-prometheus-exporter:

# 安裝exporter
docker run -d -p 9113:9113 
  nginx/nginx-prometheus-exporter:latest 
  -nginx.scrape-uri=http://nginx:8080/nginx_status

Prometheus配置:

scrape_configs:
-job_name:'nginx'
 static_configs:
  -targets:['localhost:9113']

關(guān)鍵告警規(guī)則:

groups:
-name:nginx_alerts
 rules:
  -alert:NginxHighConnectionUsage
   expr:nginx_connections_active/nginx_connections_accepted>0.8
   for:5m
   labels:
    severity:warning
   annotations:
    summary:"Nginx連接使用率過高"

  -alert:NginxHighErrorRate
   expr:rate(nginx_http_requests_total{status=~"5.."}[5m])/rate(nginx_http_requests_total[5m])>0.01
   for:5m
   labels:
    severity:critical
   annotations:
    summary:"Nginx 5xx錯誤率超過1%"

5.3 備份與恢復(fù)

5.3.1 配置備份

#!/bin/bash
# /usr/local/bin/backup_nginx.sh

BACKUP_DIR="/data/backup/nginx"
DATE=$(date +%Y%m%d_%H%M%S)
NGINX_DIR="/etc/nginx"

# 創(chuàng)建備份目錄
mkdir -p${BACKUP_DIR}

# 備份配置文件
tar -czf${BACKUP_DIR}/nginx_config_${DATE}.tar.gz${NGINX_DIR}

# 備份SSL證書
tar -czf${BACKUP_DIR}/nginx_ssl_${DATE}.tar.gz${NGINX_DIR}/ssl/

# 保留30天備份
find${BACKUP_DIR}-name"*.tar.gz"-mtime +30 -delete

echo"Backup completed:${BACKUP_DIR}/nginx_config_${DATE}.tar.gz"

5.3.2 配置恢復(fù)

#!/bin/bash
# 恢復(fù)配置

BACKUP_FILE=$1

if[ -z"$BACKUP_FILE"];then
 echo"Usage:$0"
 exit1
fi

# 備份當(dāng)前配置
mv /etc/nginx /etc/nginx.bak.$(date +%s)

# 解壓恢復(fù)
tar -xzf$BACKUP_FILE-C /

# 測試配置
nginx -t

if[ $? -eq 0 ];then
  nginx -s reload
 echo"Configuration restored successfully"
else
 echo"Configuration test failed, rolling back"
  rm -rf /etc/nginx
  mv /etc/nginx.bak.* /etc/nginx
fi

六、總結(jié)

6.1 技術(shù)要點回顧

反向代理和負載均衡是Nginx最核心的功能,掌握好這兩個技能,基本就能應(yīng)對大部分Web架構(gòu)需求了。

反向代理要點

proxy_pass指令是核心

代理頭設(shè)置影響后端獲取真實信息

緩沖區(qū)配置影響內(nèi)存使用和響應(yīng)速度

超時配置要根據(jù)業(yè)務(wù)調(diào)整

負載均衡要點

算法選擇:無狀態(tài)服務(wù)用least_conn,需要會話保持用ip_hash

健康檢查:生產(chǎn)環(huán)境必須配置max_fails和fail_timeout

連接復(fù)用:keepalive可以顯著提升性能

故障轉(zhuǎn)移:proxy_next_upstream配置自動重試

6.2 進階學(xué)習(xí)方向

Nginx Plus:商業(yè)版功能,主動健康檢查、動態(tài)配置、更好的監(jiān)控

OpenResty:整合Lua,實現(xiàn)復(fù)雜的業(yè)務(wù)邏輯

Envoy:云原生時代的新選擇,功能更強大

服務(wù)網(wǎng)格:Istio、Linkerd等,下一代流量管理方案

6.3 參考資料

Nginx官方文檔 - ngx_http_upstream_module: https://nginx.org/en/docs/http/ngx_http_upstream_module.html

Nginx官方文檔 - ngx_http_proxy_module: https://nginx.org/en/docs/http/ngx_http_proxy_module.html

Nginx負載均衡指南: https://docs.nginx.com/nginx/admin-guide/load-balancer/

附錄

A. 命令速查表

命令 說明
nginx -t 測試配置語法
nginx -s reload 平滑重載配置
nginx -T 輸出完整配置
curl -I http://url 查看響應(yīng)頭
ss -tlnp 查看監(jiān)聽端口
ss -ant | grep ESTAB 查看已建立的連接

B. 配置參數(shù)詳解

參數(shù) 上下文 默認(rèn)值 說明
proxy_pass location - 代理目標(biāo)地址
proxy_connect_timeout http,server,location 60s 連接超時
proxy_send_timeout http,server,location 60s 發(fā)送超時
proxy_read_timeout http,server,location 60s 讀取超時
proxy_next_upstream http,server,location error timeout 觸發(fā)重試的條件
keepalive upstream - 保持的空閑連接數(shù)
weight server 1 服務(wù)器權(quán)重
max_fails server 1 最大失敗次數(shù)
fail_timeout server 10s 失敗超時時間

C. 術(shù)語表

術(shù)語 解釋
反向代理 代理服務(wù)端,客戶端不知道真實服務(wù)器地址
正向代理 代理客戶端,服務(wù)端不知道真實客戶端地址
負載均衡 將請求分發(fā)到多臺服務(wù)器
Upstream Nginx中定義后端服務(wù)器組的指令
健康檢查 檢測后端服務(wù)器是否可用
會話保持 同一用戶的請求總是發(fā)到同一臺服務(wù)器
灰度發(fā)布 逐步將流量切換到新版本
熔斷 當(dāng)后端不可用時自動停止轉(zhuǎn)發(fā)請求

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    14

    文章

    10251

    瀏覽量

    91480
  • 負載均衡
    +關(guān)注

    關(guān)注

    0

    文章

    133

    瀏覽量

    12874
  • nginx
    +關(guān)注

    關(guān)注

    0

    文章

    186

    瀏覽量

    13110

原文標(biāo)題:Nginx反向代理+負載均衡實戰(zhàn):小白也能搭建高可用架構(gòu)

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    使用nginx實現(xiàn)tomcat負載均衡

    Nginx+tomcat+memcached實現(xiàn)負載均衡及session(交叉存儲)
    發(fā)表于 08-28 08:52

    采用Nginx反向代理解決跨域

    40Nginx反向代理功能解決跨域問題
    發(fā)表于 10-10 10:58

    nginx實現(xiàn)的負載均衡

    nginx實現(xiàn)負載均衡
    發(fā)表于 05-04 13:42

    16nginx+keepalived +zuul如何實現(xiàn)高可用及負載均衡

    學(xué)習(xí)筆記微服務(wù)-16 nginx+keepalived +zuul 實現(xiàn)高可用及負載均衡
    發(fā)表于 05-22 10:16

    Nginx和Tomcat負載均衡實現(xiàn)session共享

    Nginx和Tomcat負載均衡實現(xiàn)session共享
    發(fā)表于 09-05 10:40 ?9次下載
    <b class='flag-5'>Nginx</b>和Tomcat<b class='flag-5'>負載</b><b class='flag-5'>均衡</b>實現(xiàn)session共享

    構(gòu)建實戰(zhàn)Nginx+IIS構(gòu)筑Web服務(wù)器集群負載均衡

    構(gòu)建實戰(zhàn)Nginx+IIS構(gòu)筑Web服務(wù)器集群負載均衡
    發(fā)表于 09-05 10:56 ?4次下載
    構(gòu)建<b class='flag-5'>實戰(zhàn)</b>:<b class='flag-5'>Nginx</b>+IIS構(gòu)筑Web服務(wù)器集群<b class='flag-5'>負載</b><b class='flag-5'>均衡</b>

    apache反向代理負載均衡總結(jié)

    apache反向代理負載均衡總結(jié)(5g電源技術(shù)要求)-apache反向代理
    發(fā)表于 08-31 12:27 ?0次下載
    apache<b class='flag-5'>反向</b><b class='flag-5'>代理</b>和<b class='flag-5'>負載</b><b class='flag-5'>均衡</b>總結(jié)

    聊聊Nginx作為負載均衡器它支持的算法都有哪些?

    Nginx作為一款最流行WEB服務(wù)器軟件,同時也是一款反向代理負載均衡軟件。毫不夸張地說,Nginx
    的頭像 發(fā)表于 02-14 17:50 ?1423次閱讀

    如何使用Nginx作為應(yīng)用程序的負載均衡器?

    Nginx因其高性能和可擴展性而廣受歡迎。它是排名第一的開源Web 服務(wù)器。在本教程中,我們將學(xué)習(xí)如何使用Nginx作為應(yīng)用程序的負載均衡器? 要將
    的頭像 發(fā)表于 03-23 14:52 ?1939次閱讀

    搭建Keepalived+Lvs+Nginx高可用集群負載均衡

    ? 一、Nginx安裝 二、配置反向代理 三、配置負載均衡
    的頭像 發(fā)表于 06-25 15:39 ?4275次閱讀
    搭建Keepalived+Lvs+<b class='flag-5'>Nginx</b>高可用集群<b class='flag-5'>負載</b><b class='flag-5'>均衡</b>

    nginx使用學(xué)習(xí)之正、反向代理

    Nginx 不僅可以做反向代理,實現(xiàn)負載均衡。還能用作正向代理來進行上網(wǎng)等功能。正向
    的頭像 發(fā)表于 11-13 10:54 ?1953次閱讀
    <b class='flag-5'>nginx</b>使用學(xué)習(xí)之正、<b class='flag-5'>反向</b><b class='flag-5'>代理</b>

    如何使用nginx反向代理功能?保姆級教程!

    一關(guān)于nginxnginx是一款高性能的開源Web服務(wù)器軟件,也可以用于反向代理負載均衡等,并且具有高性能、低內(nèi)存消耗等優(yōu)點。本文我們主要講解關(guān)于
    的頭像 發(fā)表于 06-21 08:21 ?1826次閱讀
    如何使用<b class='flag-5'>nginx</b><b class='flag-5'>反向</b><b class='flag-5'>代理</b>功能?保姆級教程!

    nginx負載均衡配置介紹

    目錄 nginx負載均衡 nginx負載均衡介紹 反向
    的頭像 發(fā)表于 11-10 13:39 ?1552次閱讀
    <b class='flag-5'>nginx</b><b class='flag-5'>負載</b><b class='flag-5'>均衡</b><b class='flag-5'>配置</b>介紹

    Nginx代理轉(zhuǎn)發(fā)實戰(zhàn):零基礎(chǔ)掌握服務(wù)器流量分發(fā)技巧

    Nginx 是最常用的反向代理工具之一,一個指令 proxy_pass搞定反向代理,對于接口代理
    的頭像 發(fā)表于 12-09 12:28 ?2975次閱讀

    一文詳解Nginx負載均衡

    Nginx作為負載均衡器,通過將請求分發(fā)到多個后端服務(wù)器,以提高性能、可靠性和擴展性。支持多種負載均衡算法,如輪詢、最小連接數(shù)、IP哈希等,
    的頭像 發(fā)表于 06-25 14:51 ?1080次閱讀
    一文詳解<b class='flag-5'>Nginx</b><b class='flag-5'>負載</b><b class='flag-5'>均衡</b>