第 8 章

ELB 负载均衡实战

⏱️ 40 分钟
📝 20 题练习
备考助手

📌 核心知识点

负载均衡器选择健康检查配置SSL/TLS 终止跨区域负载均衡

ELB 负载均衡实战

📖 负载均衡器基础知识

AWS 提供三种负载均衡器产品,适用于不同场景。在 ALB 出现之前,CLB 被称为 "Elastic Load Balancer (ELB)",所以旧文档可能还会引用 "ELB"。

📒 官方文档ALB 文档NLB 文档定价

🖼️ ELB 图解补充

VPC 基础网络架构(AWS 官方)

看图重点:负载均衡器部署位置(公有/私有子网)决定暴露边界。

EC2 Security Group 基础示意(AWS 官方)

看图重点:ELB 与后端实例的 SG 规则要配对,否则健康检查会失败。

ECS 公网出站模式(AWS 官方)

看图重点:容器服务接入 ALB 前先确定公网入口还是私网入口模式。

ECS 私网出站模式(AWS 官方)

看图重点:内网服务常使用内部 ALB,避免直接公网暴露。

ECS 通过 NAT Gateway 访问外部服务(AWS 官方)

看图重点:ELB 后端出网流量路径会影响日志、更新和外部依赖调用。

IAM 策略生效逻辑(AWS 官方)

看图重点:自动化创建/更新 ELB 失败时要检查调用方 IAM 权限。

AWS 数据传输费用

看图重点:跨 AZ 负载均衡与回源路径会带来网络费用差异。

发展历史

2009年: CLB (Classic Load Balancer) 发布
2016年: ALB (Application Load Balancer) 发布
2017年: NLB (Network Load Balancer) 发布

ELB 类型对比

类型总览

类型层级协议发布年份适用场景
ALB7层HTTP/HTTPS/gRPC2016Web 应用、微服务
NLB4层TCP/UDP/TLS2017高性能、低延迟
CLB4/7层HTTP/TCP2009遗留应用 (不推荐新项目)

详细功能对比

功能CLBALBNLB
基于内容路由
静态 IP
保持客户端源 IP
WebSocket
HTTP/2
SNI (多证书)
动态端口映射
EC2 Classic 支持

Application Load Balancer (ALB)

互联网
    │
    ▼
  ALB ─────────────────────────────
    │  路径路由      │  主机路由
    ├─ /api/* ──────→ API 服务器
    ├─ /static/* ───→ 静态服务器
    └─ *.admin.com ─→ Admin 服务器

ALB 组件架构(AWS 官方)

看图重点:Listener、Rule、Target Group 是 ALB 三层核心,问题排查也按这三层走。

特点:

  • 基于内容路由 (URL、主机头、HTTP 方法)
  • 原生支持 WebSocket 和 HTTP/2
  • 支持 Lambda 目标
  • 集成 WAF 和 Cognito
  • 支持 SNI(最多 25 个 HTTPS 证书)
  • 支持 IP 目标(可路由到 VPN/Direct Connect 后的本地资源)

Network Load Balancer (NLB)

互联网
    │
    ▼
  NLB ─── 超低延迟转发 ───→ 后端服务器
    │
    ├─ TCP 端口直接映射
    ├─ 保持客户端源 IP
    └─ 每秒数百万请求

特点:

  • 极低延迟 (~100μs)
  • 静态 IP / Elastic IP
  • 保持客户端源 IP
  • 适合游戏、IoT、金融
  • 支持同一 IP 上的多个端口

Classic Load Balancer 架构(AWS 官方)

看图重点:CLB 适合遗留场景,新项目通常优先 ALB/NLB;面试和实战题都常考这个迁移思路。

负载均衡器选择

决策流程

需要基于 HTTP 内容路由?
    │
    ├── 是 → ALB
    │
    └── 否 → 需要极低延迟/静态 IP?
                │
                ├── 是 → NLB
                │
                └── 否 → ALB (更多功能)

场景建议

场景推荐原因
Web 应用ALB路径路由、WAF
微服务/ECSALB动态端口映射
API GatewayALBURL 路由
游戏服务器NLB低延迟、UDP
数据库代理NLBTCP 转发
混合云连接NLB静态 IP
遗留 EC2-ClassicCLB唯一支持

💡 建议: 即使架构很简单(只有一台服务器),也建议使用负载均衡器:

  • 升级时更灵活,无需等待 DNS 传播
  • 更容易终止 SSL
  • 未来扩展更方便

💡 负载均衡器最佳实践

1. 理解负载均衡器的 IP

# ❗ CLB 和 ALB 没有固定的外部 IP!

# 内部实际上是多个 EC2 托管的软件负载均衡器
# DNS 在它们之间分发流量
# IP 池至少包含每个可用区一个 IP
# 根据流量级别会变化

# 永远不要把 CLB/ALB 的 DNS 解析成 IP 放到 A 记录!
# 它会工作一段时间,然后突然失败!

2. 客户端 IP 获取

# CLB: 通过 X-Forwarded-For 头获取
# ALB: 通过 X-Forwarded-For 头获取
# NLB: 直接保持客户端源 IP(最大优势)

3. 预热负载均衡器

# ❗ CLB 和 ALB 需要时间扩展容量!
# 无法处理突发流量

# 如果预期有流量高峰:
# 1. 提前做负载测试让其扩展
# 2. 联系 AWS 支持进行 "pre-warm"

4. 部署策略

# 常见模式:蓝绿部署
1. 启动新版本实例
2. 将新实例加入负载均衡器目标组
3. 保持旧实例运行 1-2 小时
4. 如有问题,快速切回旧实例
5. 确认无问题后,终止旧实例

5. 证书轮换(保持 ARN)

# 轮换证书但保持相同 ARN 的方法:
1. 上传新证书(如 fuzzy.com.new)
2. 重命名旧证书(fuzzy.com → fuzzy.com.expired)
3. 重命名新证书(fuzzy.com.new → fuzzy.com)
4. 触发 ALB/CLB Listener 更新:
   # ALB: modify-listener
   # CLB: create-load-balancer-listeners

健康检查配置

ALB 健康检查

# Terraform 示例
resource "aws_lb_target_group" "app" {
  name     = "app-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id

  health_check {
    path                = "/health"
    healthy_threshold   = 2
    unhealthy_threshold = 3
    timeout             = 5
    interval            = 30
    matcher             = "200-299"
  }
}

健康检查参数

参数推荐值说明
interval30s检查间隔
timeout5s超时时间
healthy_threshold2连续成功次数
unhealthy_threshold3连续失败次数
path/health健康检查路径

健康检查端点设计

# Flask 示例
@app.route('/health')
def health_check():
    # 检查数据库连接
    try:
        db.session.execute('SELECT 1')
    except:
        return 'Database unhealthy', 503

    # 检查依赖服务
    if not redis.ping():
        return 'Redis unhealthy', 503

    return 'OK', 200

SSL/TLS 终止

ALB HTTPS 配置

客户端 ──HTTPS──→ ALB ──HTTP──→ 后端服务器
                  │
            SSL 终止点
            (ACM 证书)

配置步骤

# 1. 申请/导入证书
aws acm request-certificate \
  --domain-name example.com \
  --validation-method DNS

# 2. 创建 HTTPS 监听器
aws elbv2 create-listener \
  --load-balancer-arn $ALB_ARN \
  --protocol HTTPS \
  --port 443 \
  --certificates CertificateArn=$CERT_ARN \
  --default-actions Type=forward,TargetGroupArn=$TG_ARN

# 3. HTTP 重定向到 HTTPS
aws elbv2 create-listener \
  --load-balancer-arn $ALB_ARN \
  --protocol HTTP \
  --port 80 \
  --default-actions Type=redirect,RedirectConfig='{...}'

跨区域负载均衡

使用 Global Accelerator

用户 (悉尼) ─→ Edge Location ─→ AWS 网络 ─→ ALB (悉尼)
用户 (东京) ─→ Edge Location ─→ AWS 网络 ─→ ALB (东京)
                    │
           Global Accelerator
           (Anycast IP)

Route 53 + ALB

用户 ─→ Route 53 (延迟路由) ─┬→ ALB (ap-southeast-2)
                            └→ ALB (ap-northeast-1)

高级配置

粘性会话

# 启用应用 Cookie 粘性
aws elbv2 modify-target-group-attributes \
  --target-group-arn $TG_ARN \
  --attributes Key=stickiness.enabled,Value=true \
               Key=stickiness.type,Value=app_cookie \
               Key=stickiness.app_cookie.cookie_name,Value=JSESSIONID

连接耗尽

# 设置耗尽超时
aws elbv2 modify-target-group-attributes \
  --target-group-arn $TG_ARN \
  --attributes Key=deregistration_delay.timeout_seconds,Value=30

跨可用区负载均衡

# ❗ 默认情况下,CLB 不会将流量路由到其他 AZ 的实例!
# 这会导致 503 错误

# 如果每个 AZ 少于 2 个后端实例,
# 必须启用跨区域负载均衡:

aws elb modify-load-balancer-attributes \
  --load-balancer-name my-clb \
  --load-balancer-attributes \
  '{"CrossZoneLoadBalancing":{"Enabled":true}}'

⚠️ 常见陷阱

1. IP 地址问题

# ❗ CLB/ALB IP 会变化!

# 问题:
# - 某些客户端/反向代理缓存 DNS 太久
# - Java 默认 DNS TTL 可能导致问题
# - nginx 只在启动时解析后端

# 解决:
# - 调整 Java JVM TTL 设置
# - nginx 使用动态解析配置
# - 企业客户需要静态 IP 则用 NLB

2. DNS 缓存问题

# ❗ 有可能 IP 在客户之间回收,冷却期很短

# 风险:
# 如果缓存 IP 且不使用 SSL 验证服务器,
# 可能收到其他服务/公司的响应!

# 作为服务运营商,你可能会收到其他公司客户的请求

3. 健康检查配置不当

# ❗ 过于激进的健康检查会导致服务不可用

# 错误配置:
# - 太快移除不健康实例
# - 太慢添加回健康实例
# - 与 Auto Scaling 配合时更危险

# 正确做法:
# - 给实例足够时间启动
# - 设置合理的阈值

4. CLB 特定问题

# 🔸 CLB HTTPS 监听器不支持 SNI
# 解决方案:
# - 使用带 SAN 的证书
# - 使用 TCP 监听器,在后端终止 SSL

# 🔸 CLB 使用内部 HTTP keep-alives
# 不同客户端的请求可能在同一内部 TCP 连接
# 不要假设同一连接上的请求来自同一客户

# 🔸 CLB 不支持复杂路由规则
# 如需正则表达式 URL 路由,需用 HAProxy

5. ALB 特定问题

# 🔸 HTTP/2 只支持 HTTPS(不支持明文 HTTP/2)
# 🔸 HTTP/2 只面向外部客户端,不支持到后端的 HTTP/2
# 🔸 只支持 HTTP 路由,不支持端口级 TCP 路由

# 🔸 健康检查端口限制:
# 只能使用实例级固定端口或与应用端口相同
# 无法配置每个目标不同的健康检查端口

# 🔸 无健康目标时,所有请求路由到所有目标
# 服务启动期间健康检查失败时,请求仍会到达

6. NLB 特定问题

# 🔸 VPC Peering 限制
# 其他 VPC 的 EC2 客户端连接 NLB 有限制
# 除非客户端是 C5、i3.metal 或 M5 实例类型
# 且两个 VPC 必须在同一区域

# 🔸 AWS 不愿意提升 NLB 限额
# 默认每区域 20 个,ALB/CLB 容易提升,NLB 不容易

7. 资源限制

# 每区域默认限制(2024年):
ALB: 50 个
NLB: 50 个
CLB: 20 个

# ALB 和 CLB 容易申请提升
# NLB 较难提升

8. SSL 证书问题

# ❗ 设置 ACM 自动续期提醒

# ALB SNI 限制:每个负载均衡器最多 25 个证书

9. 超时设置

# ❗ ALB 超时必须小于后端超时
# 否则 ALB 会在后端响应前关闭连接

# 建议设置:
# ALB 连接超时: 60 秒
# 后端应用超时: 90 秒

10. 安全组配置

# 🔸 CLB 到同一子网后端实例的流量会经过 NACL 评估!
# (EC2 到 EC2 同子网流量不会)

# 如果移除了默认的 '0.0.0.0/0 ALLOW' 规则,
# 必须添加允许健康检查端口和监听器端口的规则

📚 本章小结

  • ALB 适合 Web 应用和微服务(路径/主机路由、WAF)
  • NLB 适合高性能和需要静态 IP 的场景
  • CLB 只用于遗留应用和 EC2-Classic
  • CLB/ALB 没有固定 IP,不要将 DNS 解析结果硬编码
  • 预热负载均衡器以应对突发流量
  • 健康检查配置不当会导致服务不可用
  • 启用跨可用区负载均衡避免 503 错误
  • Java 和 nginx 需要特别注意 DNS TTL 配置
📝 章节练习 (20 题)
开始练习