[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| upstream | n. | /ˈʌpstriːm/ | 上游/后端组(一组后端服务器) |
| weight | n. | /weɪt/ | 权重(按比例分发请求) |
| round-robin | n. | /raʊnd ˈrɒbɪn/ | 轮询(按顺序轮流分发) |
| ip_hash | n. | /aɪ piː hæʃ/ | IP 哈希(同一 IP 固定到同一台,会话保持) |
| least_conn | n. | /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 使配置生效并验证分发 ✅