深色模式
负载均衡 SLB/ALB
摘要:负载均衡是公网流量的唯一入口,承担分发与高可用两件事。本文讲清监听器与后端服务器组的配置、健康检查怎么设才不会误剔除、TLS 证书如何挂载,以及常见的 502/504 排查思路。
适用环境
bash
# 本地终端 + 两台以上后端云服务器(均运行同一服务)
which curl openssl
curl --version | head -1
# 后端机上
ss -lntp | grep 80801
2
3
4
5
2
3
4
5
操作步骤
一、选对类型
| 类型 | 工作层次 | 适用 |
|---|---|---|
| 四层(NLB / LVS) | TCP/UDP | 高性能、长连接、WebSocket、自建网关 |
| 七层(ALB / HTTP) | HTTP/HTTPS | 按域名/路径路由、TLS 卸载、Header 改写 |
绝大多数 Web 业务用七层;需要极低延迟或自定义协议时用四层。
二、创建负载均衡与后端组
bash
# 创建 ALB(AWS 示例),需至少两个公有子网
aws elbv2 create-load-balancer --name web-alb \
--subnets subnet-pub-a subnet-pub-b --security-groups sg-alb --scheme internet-facing
# 创建后端服务器组
aws elbv2 create-target-group --name web-tg \
--protocol HTTP --port 8080 --vpc-id vpc-0abc \
--health-check-path /healthz --health-check-interval-seconds 10 \
--healthy-threshold-count 2 --unhealthy-threshold-count 3 \
--matcher HttpCode=200
# 注册后端实例
aws elbv2 register-targets --target-group-arn arn:aws:...web-tg \
--targets Id=i-0aaa Id=i-0bbb
# 创建监听器(80 端口)
aws elbv2 create-listener --load-balancer-arn arn:aws:...web-alb \
--protocol HTTP --port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:...web-tg1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
三、健康检查接口要写得「诚实」
健康检查接口必须真实反映实例是否可服务,但不要依赖外部组件(数据库、下游接口):
python
# /healthz 示例:只检查进程自身存活,避免下游抖动导致全量剔除
from http.server import BaseHTTPRequestHandler, HTTPServer
class H(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(b"ok")
def log_message(self, *a): pass
HTTPServer(("0.0.0.0", 8080), H).serve_forever()1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
注意
健康检查一旦依赖数据库,数据库抖动会让负载均衡把所有实例判定为不健康,导致「明明机器是好的但全站 503」。正确的做法是:健康检查只看自身,深度依赖放到独立的 /ready 接口用于人工判断。
四、挂载 TLS 证书
bash
# 上传自有证书(需提供证书链与私钥)
aws acm import-certificate --certificate fileb://fullchain.pem \
--private-key fileb://privkey.pem --certificate-chain fileb://chain.pem
# 443 监听器,做 TLS 卸载
aws elbv2 create-listener --load-balancer-arn arn:aws:...web-alb \
--protocol HTTPS --port 443 --certificates CertificateArn=arn:aws:acm:... \
--ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
--default-actions Type=forward,TargetGroupArn=arn:aws:...web-tg
# 80 强制跳转 443
aws elbv2 modify-listener --listener-arn arn:aws:...listener-80 \
--default-actions '[{"Type":"redirect","RedirectConfig":{"Protocol":"HTTPS","Port":"443","StatusCode":"HTTP_301"}}]'1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
五、验证分发与健康状态
bash
# 查看后端健康状态
aws elbv2 describe-target-health --target-group-arn arn:aws:...web-tg \
--query 'TargetHealthDescriptions[].[Target.Id,TargetHealth.State,TargetHealth.Reason]' --output table
# 多次请求验证是否轮询分发(后端可返回自己的 hostname 便于观察)
for i in $(seq 1 10); do curl -s http://<ALB域名>/ | head -1; done
# 验证证书
openssl s_client -connect <域名>:443 -servername <域名> </dev/null 2>/dev/null \
| openssl x509 -noout -dates -subject
# 验证跳转
curl -sI http://<域名>/ | head -31
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
六、502 / 504 怎么分
- 502 Bad Gateway:后端主动拒绝或连接被重置——检查后端进程是否存活、端口是否监听、安全组是否放通。
- 504 Gateway Timeout:后端处理超时——检查后端是否有慢查询/死锁,或调大负载均衡超时时间。
bash
# 绕过负载均衡直接打后端,快速定位是 LB 问题还是后端问题
curl -s -o /dev/null -w "%{http_code} %{time_total}\n" http://<后端内网IP>:8080/1
2
2
验证
- [ ]
describe-target-health中所有预期实例状态为healthy - [ ] 连续 10 次请求能看到流量分发到不同后端
- [ ] HTTP 访问自动跳转 HTTPS,证书有效期正常且未过期
- [ ] 停掉一台后端的应用,负载均衡仍能正常服务(自动剔除)
常见坑
- 后端安全组没对 LB 放通:LB 健康检查一直失败,表现为所有实例 unhealthy。
- 健康检查路径返回 301/302:负载均衡默认只认 200,跳转会被判为不健康,需调整 matcher 或直接让健康检查路径返回 200。
- 会话粘滞(Sticky)乱开:粘滞会让流量分布不均,只在确实需要会话保持时才开。
- 只挂一个可用区:单 AZ 故障等于全站不可用,创建时必须跨至少两个 AZ。
- 忘了开启访问日志:排查线上问题时没有请求日志,很难还原现场。