我最早用 AWS 的时候,负载均衡这块还只有经典那一套,后来看着它一步步长成现在这个庞大的家族。很多刚接触云原生的朋友,上来就被 ALB、NLB、CLB、GWLB 这些缩写搞得头大,再加上 Target Group、Listener、健康检查这些概念,很容易绕晕。这篇文章不打算写成官方文档的翻译版,而是把我自己这几年在项目里实际用下来的一些理解、选型思路和踩坑经验整理出来。不管是刚入门想搞懂 ELB 是干嘛的,还是已经在用但想优化一下架构,这篇文章应该都能给你一些参考。
1. 先搞清楚 Elastic Load Balancing 是什么,以及它解决了什么问题
1.1 没有负载均衡的时代,我们是怎么扛流量的
在聊 ELB 之前,先回忆一下没有负载均衡的日子。早期做 Web 服务,最原始的做法就是一台服务器跑 Nginx 或者 Apache,用户直接通过 IP 访问。业务量小的时候没问题,但一旦流量涨起来,或者服务器硬件出了故障,整个服务就瘫了。
后来大家开始用多台服务器,但在应用层手写一套流量分配逻辑并不现实。你需要在前面放一个入口,让所有请求先打到这里,再由它决定把请求转发给哪台后端机器。这就是负载均衡器的雏形。
那时候也有硬件负载均衡设备,比如 F5、Citrix NetScaler,性能确实强悍,但价格也相当感人,动辄几十万上百万。对于初创团队或者中小型项目来说,硬件方案根本不在考虑范围内。
1.2 AWS 给负载均衡做的“云化”改造
AWS 推出 Elastic Load Balancing 的思路,就是把传统硬件负载均衡的能力搬到云上,做成一个完全托管、按需使用、可以弹性伸缩的服务。
所谓“Elastic”体现在几个地方:
- 容量弹性:不需要提前预估流量峰值去采购设备,ELB 会根据实际流量自动扩展自身的处理能力。
- 后端弹性:后端的 EC2 实例可以随时增减,负载均衡器会自动发现新加入的实例,也会自动把故障实例摘除。
- 成本弹性:按实际使用量付费,没有流量的时候几乎不花钱,不像买硬件那样先砸一笔固定资产。
ELB 在 AWS 的架构里扮演的是“流量入口”的角色。它会接收来自客户端的请求,然后按照你配置的规则,把请求分发到后端的多个目标上。这些目标可以是 EC2 实例、IP 地址、Lambda 函数,甚至是容器服务里的 Pod,具体取决于你用的是哪种类型的负载均衡器。
1.3 一句话理解 ELB 的核心价值
如果让我用一句话概括,ELB 就是 AWS 帮你提前做好、可以随时启用的一套高可用流量分发系统。你不用关心它底层跑了几台机器、网络怎么冗余、证书怎么部署,只需要在控制台上点几下,把后端服务挂上去,它就能帮你把流量均匀地分下去,同时自动处理后端故障和流量波动。
对于大多数业务来说,ELB 是架构里“标配”的一环,几乎没有替代方案。自建 Nginx 或者 HAProxy 当然可行,但你需要自己处理双机热备、健康检查脚本、证书运维、流量监控等一系列问题。用 ELB 虽然少了一些底层的控制力,但换来的是稳定性和极低的运维成本。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ELB 家族的四个成员,怎么选才不后悔
2.1 Classic Load Balancer:老前辈,能不用就别用了
Classic Load Balancer(CLB)是 ELB 的第一代产品,2019 年之前它是唯一的选择,所以很多老项目里都能看到它的身影。它支持 HTTP、HTTPS、TCP 和 SSL 协议,可以在第 4 层和第 7 层做一些基础的转发。
但 CLB 的问题在于它太“简单”了:
- 不支持基于 HTTP 路径的转发规则,一个 CLB 只能对应一组后端,想按
/api、/admin分流做不到。 - 没有原生的 HTTP/2、gRPC 支持。
- 不支持 WebSocket 长连接(后来通过更新支持了,但配置起来比较费劲)。
- 和容器服务的集成不太好,很难直接配合 ECS 或 EKS 的动态端口映射。
AWS 官方已经明确说了,推荐所有新项目都使用 ALB 或 NLB,CLB 只建议存量项目继续用着,不做迁移的情况下维持现状。我的建议是:如果项目还处于规划阶段,直接用 ALB 或 NLB;如果已经在跑 CLB,找一个合适的窗口期迁移掉,越早越好,因为 AWS 对 CLB 的更新投入已经非常少了。
2.2 Application Load Balancer:HTTP/HTTPS 流量的最佳选择
ALB 工作在 OSI 模型的第 7 层(应用层),是现在 AWS 上处理 HTTP/HTTPS 流量的主力服务。它最有竞争力的特点就是“内容感知”能力。
说得直白点,ALB 在看一个请求的时候,不只是看到目标 IP 和端口,它还会看 HTTP 请求的路径、Header、查询参数、请求方法,然后根据你定义的规则来转发流量。这意味着你可以用同一个 ALB 入口,把流量按路径分流到不同的后端服务,这在微服务架构里几乎是标配玩法。
举个例子,一个电商网站可能有用户服务、商品服务、订单服务三个后端。使用 ALB 的话,你只需要建一个负载均衡器,然后配置三条规则:
/*开头的路径转发给商品服务/users/*路径转发给用户服务/orders/*路径转发给订单服务
这样整个系统的入口统一为一个域名,内部的服务路由由 ALB 来处理。再加上 ALB 原生支持 HTTP/2、WebSocket、gRPC,对现代应用非常友好。
ALB 还内置了 AWS WAF(Web Application Firewall)的集成能力,可以在负载均衡层直接拦截恶意请求。对于有安全合规要求的业务来说,这个能力可以省掉很多事。
2.3 Network Load Balancer:性能怪兽,低延迟场景的最爱
NLB 工作在 OSI 模型的第 4 层(传输层),处理的是 TCP 和 UDP 流量。它不会去解析 HTTP 包里面的内容,只负责把数据包原封不动地转发到后端。
它的核心优势是极致的性能:
- 单实例可以处理每秒数百万次请求
- 延迟极低,因为它不涉及应用层解析
- 支持静态 IP 地址(可以为每个可用区分配一个固定的弹性 IP)
- 支持 TCP、UDP、TLS 直通
如果你的业务是游戏服务器、金融交易系统、实时音视频传输这些对延迟极其敏感的领域,NLB 是更合适的选择。它能把数据包快速送达后端,不做多余的检查和处理。
还有一种常见的使用方式,是把 NLB 当作 Kubernetes 集群的入口。因为 NLB 可以直接将流量转发到节点上的 NodePort,或者配合 AWS PrivateLink 将服务暴露给 VPC 内部的其他资源。
2.4 Gateway Load Balancer:新一代透明代理
GWLB 是 ELB 家族里最年轻的一员,2020 年发布。它的定位比较特殊,专门用于部署和扩展第三方虚拟设备,比如防火墙、入侵检测系统、深度包检测设备等。
传统的负载均衡器是做“转发”,而 GWLB 是做“透明流量插入”。它工作在网络层,会拦截所有经过的流量,然后通过 Geneve 协议封装,把它转发给后方的虚拟设备集群做检查处理,处理完毕后再把流量放行到实际目标。
这个服务比较垂直,日常业务开发不太用得上,但如果你所在的企业有等保要求,需要在网络边界串联一套安全审计设备,GWLB 就是非常顺手的工具。
2.5 四种负载均衡器怎么选
ALB、NLB、CLB、GWLB 并存,很多朋友在选择时会犹豫,我把它们的核心差异整理成一张表格:
| 维度 | ALB | NLB | CLB | GWLB |
|---|---|---|---|---|
| 工作层级 | 第 7 层(HTTP/HTTPS/gRPC) | 第 4 层(TCP/UDP/TLS) | 第 4 层 + 第 7 层 | 第 3/4 层(透明代理) |
| 内容感知 | 支持路径、Host、Header 路由 | 不支持 | 有限支持 | 不支持 |
| 性能表现 | 适合大部分 Web 场景 | 极高,单实例百万级并发 | 中庸 | 与第三方设备联动 |
| 静态 IP | 不支持直接分配(可通过 Global Accelerator 间接实现) | 支持 EIP 绑定 | 支持(旧特性) | 通过 Geneve 承载 |
| 协议支持 | HTTP、HTTPS、HTTP/2、WebSocket、gRPC | TCP、UDP、TLS | HTTP、HTTPS、TCP、SSL | IP 层任意协议 |
| 部署场景 | Web 应用、微服务、容器 | 低延迟场景、K8s、数据库连接 | 老项目存量 | 防火墙、IDS/IPS 等设备插入 |
选型时抓两个核心指标就好:如果流量是 HTTP/HTTPS,需要做路径分发或者粘性会话,无脑选 ALB;如果对延迟要求极高,或者业务用的是 TCP/UDP 协议,选 NLB。CLB 只在维护存量时遇到。
3. 拆开 ELB 看内核:Listener、Target Group 和健康检查到底在干嘛
3.1 Listener:流量入口的“守门员”
Listener 是负载均衡器上配置的监听端口,负责接收客户端请求。没有 Listener,负载均衡器就是一个空壳。
创建 ALB 的时候,至少要配置一个 Listener。最常见的是 80 端口的 HTTP Listener 和 443 端口的 HTTPS Listener。配置 HTTPS Listener 时,你需要选一个 SSL 证书,AWS Certificate Manager(ACM)里申请的证书可以直接绑定,省去了自己上传和轮转的麻烦。
Listener 里面定义了两部分核心内容:
- 默认规则:当请求不匹配任何自定义规则时,默认转给哪个 Target Group。
- 自定义规则:根据条件做更精细的转发,比如 URL 路径、Host 域名、请求头、HTTP 方法、源 IP 等。
ALB 的规则是支持加权配置的,你可以把 90% 的流量转给生产环境,10% 转给灰度环境,做金丝雀发布。这个操作后面细说。
3.2 Target Group:后端的“通讯录”
Target Group(目标组)是 ELB 家族里一个比较重要的抽象概念,它承载了一组具体的后端目标,以及针对这些目标的健康检查和请求转发策略。
为什么要多一层 Target Group 而不是直接把实例挂在 Listener 下面?这个设计有几个好处:
- 解耦:Listener 和 Target Group 是分离的,你可以创建一个 Target Group 然后在多个 Listener 里引用它。
- 支持不同类型的目标:同一个 Target Group 可以注册 EC2 实例、私有 IP 地址、Lambda 函数或者 ECS 任务。
- 动态调整:你需要扩容时,只需要往 Target Group 里注册新实例,负载均衡器会自动开始转发流量,不需要改动 Listener 配置。
在 ALB 中,Target Group 还有一个比较重要的属性是“目标类型”。可选的有 instance(注册 EC2 实例 ID)、ip(注册 IP 地址)、lambda(注册函数别名)。如果你用 ECS 的话,通常会把服务直接关联到 Target Group,由 ECS 自动注册和注销容器实例。
3.3 健康检查:负载均衡器的“嗅觉”
健康检查是保证服务可用性的核心机制。负载均衡器会定期向后端目标发送探测请求,判断它是否还健康。
如果探测失败,负载均衡器会把这个目标临时摘掉,不再往它转发流量;等它恢复健康之后,会自动重新加入。整个过程中,用户是无感知的。
在配置健康检查时有几个参数需要仔细调:
- 健康检查路径:常见的做法是设置一个专门用于探活的 API,比如
/health、/ping、/healthz,返回 200 或 204 状态码。最好不要拿首页或者登录接口来做健康检查,因为页面缓存可能会让结果失真。 - 间隔时间:负载均衡器每隔多少秒检查一次,默认 30 秒。时间越短发现问题越快,但也会增加后端服务器的压力。
- 超时时间和健康/不健康阈值:比如超时 5 秒,连续 3 次成功视为健康,连续 3 次失败视为不健康。
我自己在调健康检查时有一条经验:健康检查路径一定要轻量,不要在后端查数据库或者做复杂的逻辑判断。就静态返回一个 200 状态码就行,否则在流量高峰时健康检查本身会成为性能瓶颈。
3.4 粘性会话:用户请求别再乱跑了
粘性会话(Session Stickiness),也叫会话保持,是指将同一个客户端的请求始终转发到同一个后端实例上。
为什么要做粘性会话?因为有些应用把用户的登录状态或购物车信息保存在服务器本地内存或者 Session 里。如果用户的第一次请求落到了 A 实例,第二次请求被转发到 B 实例,B 实例上并没有这个用户的 Session 数据,用户就会被强制登出。
ALB 通过设置 Cookie 来实现粘性会话,有两种方式:
- 应用生成的 Cookie:负载均衡器会检查应用设置的 cookie,并尽量把带有相同 cookie 的请求转发给同一个实例。这种方式要求应用自己管理 cookie 的名称和过期时间。
- 负载均衡器生成的 Cookie:ALB 会主动生成一个名为
AWSALB的 cookie,在第一次请求时返回给客户端,之后每次请求都会附带这个 cookie。
需要提醒的是,粘性会话是把双刃剑。它确实解决了 Session 问题,但也可能导致后端负载不均衡——热门用户的请求始终落在同一台机器上。如果你的应用是无状态的,或者已经用 Redis 这类外部存储来管理 Session,最好关闭粘性会话,让流量更均匀地分配到各个实例上。
4. 实操案例:用 ALB 给一套微服务架构做流量入口
4.1 场景设定与架构规划
假设我们要部署一个典型的电商系统,包含三个服务:
- 前端静态资源服务(Nginx,负责 HTML、CSS、JS 和图片)
- 后端 API 服务(Spring Boot 或 Node.js)
- 管理后台服务(React + API,只允许内部人员访问)
架构规划如下:
- 一个 ALB 作为统一流量入口,绑定 ACM 的 SSL 证书,对外只暴露 443 端口
- 创建三个 Target Group,分别对应三个服务
/*默认转发给前端静态资源服务/api/*按路径转发给后端 API 服务/admin/*按路径转发给管理后台服务,同时加上访问 IP 白名单限制
这样设计的好处是统一入口、按路径分流,后续每加一个微服务,只需要增加一个 Target Group 和一条转发规则,不需要新增负载均衡器。
4.2 创建 Target Group
登录 AWS 控制台,在 EC2 服务里找到 Target Groups,点击“Create target group”。
关键配置项如下:
- 目标类型:选择 Instance,因为我们后端跑在 EC2 上。
- 协议和端口:HTTP 和 8080(假设 API 服务监听 8080 端口)。
- VPC:选择后端实例所在的 VPC。
- 健康检查协议/路径:选择 HTTP,路径设为
/healthz。 - 健康检查配置:间隔 15 秒,超时 5 秒,健康阈值 3,不健康阈值 3。
创建好之后,在 Target Group 的 “Targets” 页面,点击 “Register targets”,勾选对应的 EC2 实例并设置端口,点击 “Include pending” 完成注册。
4.3 创建 ALB 并配置 Listener 规则
回到 EC2 控制台的 Load Balancers 页面,点击 “Create Load Balancer”,选择 ALB。
基本配置:
- Scheme:选择 Internet-facing,让外部用户能访问。
- IP address type:选 IPv4 即可,如果双栈环境就选 Dualstack。
- VPC 和子网:至少选择两个不同可用区的子网,这是 ELB 高可用性设计的基础。负载均衡器会在每个启用子网的可用区自动创建节点,同一个可用区的后端实例才能正常接收流量。
- 安全组:入站规则只放行 80 和 443 端口,来自 0.0.0.0/0 的流量,出站不用特殊配置。
Listener 配置:
- 先创建 443 端口的 HTTPS 监听器,绑定 ACM 证书。
- 创建 80 端口 HTTP 监听器,其默认规则配置为重定向到 HTTPS 443,强制全站加密。
创建完成后,在 443 监听器上添加规则:
- 条件选 Path,配置为
/api/*,动作选 Forward,目标组选 API 服务的 Target Group - 条件选 Path,配置为
/admin/*,动作选 Forward,目标组选管理后台服务的 Target Group - 默认动作保持转发到前端资源服务的 Target Group
注意规则匹配的顺序,ALB 是按优先级从低到高逐条判断的,先匹配到的先执行。把 /api/* 的规则优先级设置为 1,/admin/* 设置为 2,默认规则优先级最高(相当于最后兜底)。
4.4 验证流量转发链路
完成上面的配置之后,把自定义域名通过 Route 53 解析到 ALB 的 DNS 名称。然后做几个测试验证链路:
bash复制# 访问前端页面
curl https://www.example.com/
# 访问 API 接口
curl https://www.example.com/api/products
# 访问管理后台
curl https://www.example.com/admin/dashboard
如果上述请求都能正常返回对应服务的响应,说明分发链路没问题。
接下来还可以做一个更实用的测试:停掉某个后端实例,模拟宕机场景。
bash复制# SSH 登录到 EC2,停止 API 服务
sudo systemctl stop api-service
等待健康检查发现实例不健康之后(约 15~30 秒),再请求 /api 相关的接口,会发现请求自动转发到了其他健康的实例,整个过程中没有 5xx 报错。这就是负载均衡加上健康检查带来的高可用效果,也是生产环境能放心滚动发版的基础。
4.5 用 ALB 做金丝雀发布:控制流量比例
ALB 的 Target Group 支持 weighted routing,可以给同一个 Listener 规则同时配置多个目标组,每个目标组设置一个权重值。这个特性用来做金丝雀发布非常方便。
具体做法是:
- 创建两个 Target Group,一个叫
service-stable,一个叫service-canary。 - 两个目标组里分别注册旧版本和新版本的实例。
- 在 Listener 规则里,把
/api/*的转发动作配两个 Target Group,权重分别设为 90 和 10。
这样新版本只接收 10% 的流量,观察一段时间如果指标稳定,再把权重调整到 50:50,最终改到 0:100,完成全量切换。
我在实际项目中这么操作过多次,比传统的蓝绿发布要平滑得多,也不需要对 DNS 做切换,全程用户无感知。
5. 绕不开的细节:跨可用区、安全组和访问日志
5.1 跨可用区负载均衡:流量要不要“串门”
VPC 里的子网分布在多个可用区,ELB 的每个节点默认只把流量转发给本可用区内的健康后端。如果一个可用区的实例全部宕机了,ALB 才会把流量转发到其他可用区的实例。
但如果有两个可用区,但实例数量不一样(比如 A 区 3 台,B 区 1 台),默认配置下,A 区的 ALB 节点只能把流量转发给 A 区的 3 台实例,B 区的节点只转发给 B 区的 1 台实例。这会导致实例资源利用不均。
开启“跨可用区负载均衡”之后,每个 ALB 节点可以把流量平均分配给所有可用区的健康实例,整体负载会更均衡。在控制台勾选 Enable cross-zone load balancing 即可。
对于流量比较大的业务,我建议开启跨可用区,可以更充分地利用所有实例的算力。不过要注意,如果开启了跨可用区,ALB 转发到不同可用区的流量,在 AWS 账单上会额外收取 Instance-hour 费用。
5.2 安全组配置:先想清楚流量方向再动手
ALB 自身的安全组需要放行从客户端进入的流量,同时它也会主动向后端实例发起健康检查和转发请求。后端的实例安全组,则必须放行来自 ALB 安全组的流量,而不是简单粗暴地放行 0.0.0.0/0。
最佳实践是使用“安全组引用安全组”的方式。具体来说:
- 在 ALB 安全组里放行 80/443 入站,来源 0.0.0.0/0
- 在后端实例的安全组里放行来自 ALB 安全组 ID 的 8080 端口入站流量
这样做的好处是不用关心 ALB 节点 IP 的变化,也不用手动维护 IP 列表。安全组之间的引用关系会自动覆盖所有 ALB 节点。
5.3 访问日志:出了故障要能“翻旧账”
ALB 和 NLB 都支持启用访问日志功能,写入到指定的 S3 存储桶。日志包含的信息非常完整,有客户端 IP、请求路径、状态码、请求处理时间、User-Agent 等。
开启方式很简单:
- 在 S3 控制台创建一个存储桶,并配置好存储桶策略,允许 ELB 账户写入。
- 在负载均衡器的 Attributes 里,把 “Access logs” 开关打开,指定存储桶和前缀。
生产环境建议必须开启访问日志,因为它是排查问题最重要的数据来源之一。比如后端的接口突然出现大量 502,通过访问日志可以看到具体是哪些请求失败了、耗时多久、后端实例 IP 是多少,能快速定位问题范围。
5.4 连接超时与空闲超时:调整参数让长连接不掉线
ALB 默认的空闲超时时间是 60 秒。也就是说,如果客户端和 ALB 之间的连接超过 60 秒没有任何数据交互,ALB 会主动断开连接。
如果你的业务有 WebSocket 长连接,或者是 SSE(Server-Sent Events)推送场景,需要把这个值调大。具体路径是:负载均衡器 → Attributes → Idle timeout,改成 300 秒甚至更长。
踩过一次坑:某次项目里用 WebSocket 做实时消息推送,客户端每 55 秒会收到一条心跳包,按道理不会触发超时。但架不住有一次后端处理逻辑耗时过长,心跳包晚到了几秒,连接正好被 ALB 断了。排查了很久才发现是默认 60 秒超时导致的问题。调长超时时间之后,问题彻底消失。
6. 常见问题与排查技巧实录
6.1 后端起服后一直报 502 错误
502 是所有 ALB 用户遇到最多的错误,代表 ALB 无法从后端目标获取有效响应。
排查步骤:
- 先看 Target Group 里实例的健康状态,如果显示 unhealthy,后端服务大概率有问题,检查进程是否正常监听端口。
- 如果健康状态正常但仍然 502,看后端服务是否正确处理来自 ALB 的请求。有一个常见原因:后端服务没有监听预期的端口,或者监听在
127.0.0.1而不是0.0.0.0。 - 检查安全组。确认后端实例的安全组放行了来自 ALB 安全组的流量。
- 检查后端服务的响应时间。如果后端处理请求耗时超过 60 秒,ALB 会在超时后返回 504,而不是 502,但 502 也有可能是后端主动断开连接导致的。
在 Nginx 作为前端,ALB 作为负载均衡的架构里,经常出现 502 的原因是 Nginx 的 proxy_read_timeout 设置得太短,导致 ALB 还没收到完整的响应,Nginx 就把连接断掉了。把 proxy 相关的超时时间调大一些往往能解决问题。
6.2 从 ALB 看到的客户端 IP 不对
如果你在 Nginx 的 access log 里看到所有请求都来自同一个 IP,而这个 IP 不是真实用户的 IP,那是因为 ALB 在转发请求时,会把客户端的原始 IP 放在 X-Forwarded-For 请求头里,但默认的 remote_addr 是 ALB 的节点 IP。
解决办法是在后端的 Nginx 配置里加上:
nginx复制set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Nginx 会把 X-Forwarded-For 头里的最后一个 IP 作为真实客户端 IP 记录下来。需要注意 set_real_ip_from 要填 ALB 节点所在的 VPC CIDR 网段,不要填成公网地址,否则会引入安全风险。
6.3 健康检查频繁抖动
健康检查状态在 healthy 和 unhealthy 之间来回切换,最常见的原因是健康检查阈值设置得太小。比如阈值设为 2,后端服务只要稍微慢一点,连续两次探测超时就判定为不健康;下一次探测成功又立刻恢复,这就造成了抖动。
另外还要注意健康检查的 interval 和 timeout 的组合。timeout 必须小于 interval,如果后端响应时间本身就接近 timeout,实际上每次探测都会非常勉强,很容易不稳定。
建议把健康阈值和不健康阈值都设置为 3,同时不要用复杂的后端逻辑做健康检查,宁可多探一次,也不要误杀正常实例。
6.4 ALB 的 DNS 解析到多个 IP
ALB 有一个固定的 DNS 域名,而不是固定的 IP。因为 ALB 本身会根据流量自动扩展,每个可用区都有一个或多个节点,所以 DNS 解析会返回多个 IP。
这带来一个好处:客户端本身也会做简单的负载均衡,随机选一个 IP 发起请求。但也有些老旧的客户端不兼容多 A 记录的 DNS 解析,只认第一个 IP。这种情况下,可以考虑在网络层前面加一个固定 IP 的入口,比如 AWS Global Accelerator 或 CloudFront。
如果你有“让防火墙只放行特定 IP”的需求,可以直接用 NLB 绑定弹性 IP,但 NLB 不具备 ALB 的路径路由能力。要兼顾两者的话,可以用 NLB 在前、ALB 在后的串联架构,代价是多一跳的网络延迟,以及 NLB 本身的费用。
6.5 常见问题速查表
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 502 Bad Gateway | 后端无响应、端口错误、安全组未放行 | 检查 Target Group 健康状态、进程监听、安全组 |
| 504 Gateway Timeout | 后端处理超时、空闲超时过短 | 查看后端日志耗时、调整 idle timeout |
| 健康检查失败 | 路径错误、后端服务未监听预期端口 | 手动 curl 健康检查路径验证 |
| 粘性会话失效 | Cookie 被应用覆盖或清除 | 检查应用是否修改 AWSALB cookie |
| 客户端 IP 显示为内网地址 | 未正确解析 X-Forwarded-For | 配置 Nginx 的 real_ip 模块 |
| 后端负载不均衡 | 未开启跨可用区、粘性会话影响 | 开启 cross-zone、检查实例权重 |
7. 关于成本和资源优化的建议
7.1 ELB 的费用构成
ELB 的计费由两部分组成:
- LCU(Load Balancer Capacity Unit):一个 LCU 包含一定数量的新建连接数、活跃连接数、处理流量字节数和规则评估数,取这几项里消耗最大的那项来计费。LCU 的设计很巧妙,它把负载均衡的性能消耗折算成一个统一单位,按实际使用量收费。
- 每小时运行费:每个负载均衡器按小时收取基础费用。
对于大多数中小项目来说,ELB 每月的账单不会太高,几十到几百美元的量级。但如果流量爆发,LCU 消耗会显著上升,需要留意控制台里的 CloudWatch 指标,尤其是 ConsumedLCUs 这个指标。
ALB 的 LCU 量级计算比较复杂,但用起来不用太担心,绝大多数场景下每个 LCU 对应一千万次左右的小型请求,只有流量非常大的业务才需要做成本规划。
7.2 冗余和节省:能合并就合并
在成本优化上,比较实用的策略是尽量合并负载均衡器,而不是一个服务就建一个。
举例来说,如果你有 10 个微服务,为每个服务单独建一个 ALB,不仅管理麻烦,费用也会线性增长。合理做法是用一个 ALB 加多个 Target Group,通过路径或者 Host 头来做路由。这样虽然单个 ALB 的流量会增大,但整体上比建 10 个 ALB 便宜得多。
另外要注意在开发环境上用最低规格的负载均衡器即可,不需要像生产环境那样配置很多条规则。开发环境可以关闭访问日志、关闭跨可用区,甚至直接用 NLB 而不是 ALB,能省则省。
7.3 配合 Auto Scaling 实现真正的“弹性”
ELB 单独使用只是完成了负载均衡的工作,真正的弹性架构还需要和 Auto Scaling 配合。
常见的做法是:给 Target Group 配置一个 Auto Scaling Group,设置 CPU 使用率超过 70% 就扩容,低于 30% 就缩容。这样 ELB 负责把流量分发到所有健康实例上,Auto Scaling 负责根据负载增减实例数量,整个系统才能真正实现弹性伸缩。
Auto Scaling Group 与 Target Group 关联之后,新增的 EC2 实例会自动注册到 Target Group 中,生命周期结束时也会自动注销,整个过程不需要人工干预。这是云上高可用架构的完整闭环。
从我个人的实践体验来看,ELB 虽然是一个托管服务,不需要你花太多精力去运维,但它的配置直接决定了整个系统的流量路径和故障恢复能力。把 Listener、Target Group、健康检查、安全组这些基础概念理解透,再配合 Auto Scaling 和 CloudWatch 监控,整个架构的稳定性和可维护性会提升一个档次。最后再提醒一句,每个项目上线前,记得在非生产环境做一次完整的“杀实例演练”,确认健康检查摘除实例的机制是按预期工作的——这个动作在关键时刻能救命。
