Lecture04-Nginx-负载均衡配置

文章目录

    [toc]

    单词词性音标含义
    upstreamn./ˈʌpstriːm/上游/后端组(一组后端服务器)
    weightn./weɪt/权重(按比例分发请求)
    round-robinn./raʊnd ˈrɒbɪn/轮询(按顺序轮流分发)
    ip_hashn./aɪ piː hæʃ/IP 哈希(同一 IP 固定到同一台,会话保持)
    least_connn./liːst kəˈnekʃn/最少连接(谁空闲给谁)

    Lecture04-Nginx-负载均衡配置

    1、本节讲什么

    用 upstream 配多台后端服务器,让 Nginx 把请求分发过去。掌握最常见的轮询、权重、IP 哈希、最少连接四种策略。这是 Nginx 最核心的实战配置。

    2、概念速览

    upstream(上游/后端组):在 nginx.conf 里定义一组后端服务器,Nginx 按策略把请求分给它们。

    四种内置策略:

    策略写法分发逻辑适用
    轮询(默认)server 地址;(不写指令)按顺序轮流各台性能相近
    权重server 地址 weight=2;按权重比例分发各台性能不同
    IP 哈希ip_hash;同一 IP 固定到同一台需要"会话保持"
    最少连接least_conn;谁空闲给谁请求耗时差异大

    3、照着做

    ① 在 /etc/nginx/nginx.conf 的 http { } 里加 upstream(在 server 块外面):

    http {
        upstream flower_backend {          # 后端组名字,随意取
            server 192.168.1.10:8080;      # 后端1:你的 SpringBoot
            server 192.168.1.11:8080;      # 后端2
            # 想用权重:server 192.168.1.10:8080 weight=2;
            # 想用 IP 哈希:去掉上面两行注释位置,改为 ip_hash; 开头一行
            # 想用最少连接:改为 least_conn; 一行
        }
    
        # server 是 Nginx 虚拟出来的一个服务器,有处理 HTTP 请求的功能
        server {
            listen 80; # listen 是配置虚拟服务器监听的端口号
            location / { # location 表示定义的含义,当前端访问 80 端口的根目录(/)时,按照下面配置定位
                proxy_pass http://flower_backend;   # 把请求转发给这个后端组
                proxy_set_header Host $http_host;   # 透传原始 Host(含端口)。⚠️ 不要用 $host——它会把端口剥掉,后端会误判端口为 80
                proxy_set_header X-Real-IP $remote_addr;  # 透传客户端真实 IP
            }
        }
    }
    

    ② 测试语法并重载

    sudo nginx -t
    sudo systemctl reload nginx
    

    ③ 验证分发

    • 让两台后端各返回不同的标识(如后端1 页面写"我是 A",后端2 写"我是 B")。
    • curl http://localhost 多刷几次,看是否轮询到 A、B 交替出现(轮询默认)。
    • 想更直观,可配 least_conn 或 ip_hash 再观察差异。

    4、常见疑问

    • Q:proxy_pass 后面跟什么? A:跟后端组名 http://flower_backend(就是 upstream 起的名字)。它会把 location 匹配到的请求整个转发过去。

    • Q:后端一台挂了会怎样? A:Nginx 会把请求分给其他存活的;max_fails + fail_timeout 还能让 Nginx 检测到挂掉后暂时跳过它。默认几秒内连接失败会转给别的。

    • Q:要不要 HTTPS? A:本节是基础(HTTP)。生产会用 HTTPS(listen 443 ssl + 证书),原理一样,只是多了证书配置。先跑通 HTTP 再说。

    • Q:会话保持(用户登录后下次还在同一台)怎么办? A:用 ip_hash(同一 IP 固定同一台)最省事;或后端共享 session(如 Redis)。前端教程里"登录态"那套在这里对应 ip_hash。

    • Q:后端返回的端口永远是 80,看不到轮询到哪台? A:99% 是 proxy_set_header Host $host; 惹的祸。Nginx 的 $host 变量只取主机名、剥掉端口——浏览器访问 :9999,转发给后端时 Host 头变成了 192.168.100.100(无端口),后端 Spring 按 HTTP 默认端口 80 处理。

      变量值带不带端口
      $host192.168.100.100❌ 剥掉了
      $http_host192.168.100.100:9999✅ 原始 Host 头

      改成 proxy_set_header Host $http_host; 即可。

      注意:如果你想在响应里看到"自己被轮询到了哪台后端"(21000 / 22000 / 23000),后端代码要用 request.getLocalPort()(自己监听的端口),而不是 request.getServerPort()(请求里的端口)——后者拿到的是浏览器访问的端口,不是后端自己的。



    5、本节验证

    • 会用 upstream 定义后端组并在 server 里转发 ✅
    • 会配置轮询 / 权重 / ip_hash / least_conn 四种策略 ✅
    • 会用 nginx -t + reload 使配置生效并验证分发 ✅
    end