一条命令搞定 Nginx 高可用:AWS NLB 负载均衡完全指南#
问题场景#
你的网站放在一个 nginx 服务器上,业务增长后发现:
- 单点故障风险高(服务器宕机 = 网站离线)
- 流量突增时无法扩容
- 无法做滚动更新(更新 nginx 配置时需要停机)
怎么办? 用 AWS Network Load Balancer(NLB)给 nginx 加一个"智能管家"。
🎯 核心方案(一句话)#
在两个 nginx 实例前部署 NLB,让它自动分发流量、检测故障、智能转移。
互联网
↓
🔷 NLB(固定入口点)
├→ 🟢 nginx-1(AZ-A)
└→ 🟢 nginx-2(AZ-B)
📊 架构对比#
❌ 旧架构:单点 Nginx#
互联网 → nginx-1 → 网站
(如果宕机 = 全死)
问题:
✅ 新架构:NLB + 双 Nginx#
互联网 → NLB(固定 DNS + IP)
├→ nginx-1(自动故障转移)
└→ nginx-2(自动故障转移)
优势:
- 高可用(一个宕机,自动切另一个)
- 自动负载均衡
- 零停机更新
🔧 部署步骤(实操)#
第 1 步:准备两个 Nginx 实例#
在两个**不同的可用区(AZ)**部署 nginx:
1
2
3
4
5
6
7
8
9
10
11
12
13
| # AZ-A 中的 nginx-1
aws ec2 run-instances \
--image-id ami-xxxxxxxx \
--instance-type t3.medium \
--subnet-id subnet-azA \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=nginx-1}]'
# AZ-B 中的 nginx-2
aws ec2 run-instances \
--image-id ami-xxxxxxxx \
--instance-type t3.medium \
--subnet-id subnet-azB \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=nginx-2}]'
|
关键点: 一定要在不同 AZ,这样即使整个可用区宕机,服务也能继续。
第 2 步:创建 NLB#
1
2
3
4
5
6
| # 创建 NLB
aws elbv2 create-load-balancer \
--name my-nlb \
--subnets subnet-azA subnet-azB \
--type network \
--scheme internet-facing
|
输出示例:
LoadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:xxx:loadbalancer/net/my-nlb/xxx
DNSName: my-nlb-xxx.elb.us-east-1.amazonaws.com
现在你有一个固定的 DNS 入口点了! 这个 DNS 永远不会变,即使后端实例换 IP。
第 3 步:创建目标组(Target Group)#
NLB 需要知道要转发流量到哪些实例:
1
2
3
4
5
6
7
8
9
10
11
| # 创建目标组
aws elbv2 create-target-group \
--name nginx-targets \
--protocol TCP \
--port 80 \
--vpc-id vpc-xxxxxxxx
# 将两个 nginx 实例加入目标组
aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:xxx:targetgroup/nginx-targets/xxx \
--targets Id=i-nginx1 Id=i-nginx2
|
第 4 步:配置健康检查#
这是关键!NLB 会自动检测 nginx 的健康状态,故障实例会自动被剔除:
1
2
3
4
5
6
7
8
| aws elbv2 modify-target-group \
--target-group-arn arn:aws:elasticloadbalancing:xxx:targetgroup/nginx-targets/xxx \
--health-check-enabled \
--health-check-protocol TCP \
--health-check-port 80 \
--healthy-threshold-count 3 \
--unhealthy-threshold-count 3 \
--health-check-interval-seconds 30
|
这是什么?
- 每 30 秒检查一次 nginx 的 80 端口
- 连续 3 次健康 → 流量转发到这个实例
- 连续 3 次失败 → 停止转发(等待修复)
第 5 步:创建监听器(连接 NLB 和目标组)#
1
2
3
4
5
| aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:xxx:loadbalancer/net/my-nlb/xxx \
--protocol TCP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:xxx:targetgroup/nginx-targets/xxx
|
大功告成! 现在:
- 流量进来 → NLB 接收
- NLB 根据健康检查的结果 → 分发到 nginx-1 或 nginx-2
- 其中一个故障 → 自动全部转移到另一个
📊 工作流程图解#
正常状态#
用户请求 → NLB
├→ nginx-1(✅ 健康,接收 50% 流量)
└→ nginx-2(✅ 健康,接收 50% 流量)
nginx-1 故障#
用户请求 → NLB
├→ nginx-1(❌ 故障,不转发)
└→ nginx-2(✅ 健康,接收 100% 流量)
[NLB 自动检测故障,无需人工干预]
nginx-1 恢复#
用户请求 → NLB
├→ nginx-1(✅ 恢复,接收 50% 流量)
└→ nginx-2(✅ 健康,接收 50% 流量)
[自动恢复,无需重启]
💡 高级用法#
1. 跨区域容错#
当前架构: 两个 AZ(区域 A 和区域 B)
- 区域 A 宕机 → 自动切到区域 B ✅
- 区域 B 宕机 → 自动切到区域 A ✅
- 两个都宕机 → 没救了 ❌
更强大的架构: 三个 AZ(区域 A / B / C)
1
2
3
4
5
6
7
8
9
10
| # 在第三个 AZ 部署
aws ec2 run-instances \
--image-id ami-xxxxxxxx \
--instance-type t3.medium \
--subnet-id subnet-azC
# 加入 NLB
aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:xxx:targetgroup/nginx-targets/xxx \
--targets Id=i-nginx3
|
2. 监控和告警#
1
2
3
4
5
6
7
8
9
10
11
| # 当有实例不健康时发告警
aws cloudwatch put-metric-alarm \
--alarm-name nginx-unhealthy \
--alarm-description "Alert when nginx is unhealthy" \
--metric-name UnHealthyHostCount \
--namespace AWS/NetworkELB \
--statistic Average \
--period 60 \
--threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--alarm-actions arn:aws:sns:us-east-1:xxx:my-topic
|
3. 流量分布调整#
想让某个实例承载更多流量?使用权重:
1
2
3
4
5
| aws elbv2 modify-target-group-attributes \
--target-group-arn arn:aws:elasticloadbalancing:xxx:targetgroup/nginx-targets/xxx \
--attributes \
Key=stickiness.enabled,Value=true \
Key=stickiness.type,Value=source_ip
|
⚠️ 常见问题#
Q1: NLB 会不会单点故障?#
A: 不会!NLB 自身已经是高可用的(多 AZ 部署),AWS 管理。
Q2: NLB 成本贵吗?#
A: 按 LCU(Load Balancer Capacity Unit)计费,通常 $0.006/LCU/小时。
Q3: 如何做到零停机更新 nginx 配置?#
A: 使用连接池排空(connection draining):
1
2
3
| aws elbv2 modify-target-group-attributes \
--target-group-arn arn:aws:elasticloadbalancing:xxx:targetgroup/nginx-targets/xxx \
--attributes Key=deregistration_delay.timeout_seconds,Value=30
|
现在:
- 更新 nginx-1 配置
- NLB 自动停止向 nginx-1 发送新连接
- 现有连接完成(最多 30 秒)
- nginx-1 重启
- 完全透明,用户零感知
Q4: 可以同时支持 HTTP 和 HTTPS 吗?#
A: 可以!创建两个监听器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # HTTP 监听器
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:xxx:loadbalancer/net/my-nlb/xxx \
--protocol TCP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=xxx
# HTTPS 监听器
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:xxx:loadbalancer/net/my-nlb/xxx \
--protocol TLS \
--port 443 \
--certificates CertificateArn=arn:aws:acm:xxx \
--default-actions Type=forward,TargetGroupArn=xxx
|
📋 快速部署清单#
🎯 效果验证#
部署完成后,你的网站:
✅ 高可用:单个 nginx 宕机不影响服务
✅ 自动故障转移:秒级切换
✅ 可扩展:需要更多容量时,直接加更多 nginx 实例
✅ 零停机更新:更新配置时用户无感知
✅ 自动负载均衡:流量均匀分发
📊 对比表#
| 方案 | 单点 Nginx | NLB + 双 Nginx |
|---|
| 可用性 | 99% | 99.99% |
| 故障转移时间 | N/A(宕机就死) | < 30 秒自动 |
| 可扩展性 | 无(单机上限) | 有(加实例即可) |
| 零停机更新 | ❌ 不行 | ✅ 可以 |
| 月成本 | ~$0 | ~$20-50 |
💰 成本分析#
月度成本估算(假设日均 1000 万请求):
| 项目 | 成本 |
|---|
| NLB 基础费 | $16.20 |
| LCU 费用 | $30-50 |
| 两个 EC2 实例(t3.medium) | $30-40 |
| 总计 | 约 $80-110/月 |
vs 单点 Nginx($30-40/月):
- 多付 $50-70/月
- 换来 99.99% 可用性和零停机更新
- 非常值得!
🚀 总结#
一句话: 用 AWS NLB 给两个 nginx 加一个"智能管家",自动分发流量、检测故障、智能转移。
三个要点:
- 跨 AZ 部署两个 nginx(提高可用性)
- NLB 自动做健康检查和故障转移
- DNS 指向 NLB,一劳永逸
一条命令启动高可用:
1
2
| # 参考上面的 5 个步骤,按顺序执行
# 从第 1 步到第 5 步,30 分钟搞定
|
下一步? 选择你的架构,开始部署吧!💪
如果有问题,欢迎留言讨论。