反向代理与网关:API Gateway 在高可用中的角色
很多团队做高可用,第一反应就是加机器、做集群。但流量进来以后怎么分?安全策略在哪执行?限流熔断谁来管?这些事,API Gateway 就是那个“看门人”。
说白了,没有网关的高可用,就像盖楼没装大门——你加再多房间也进不去。今天聊两个主流方案:Kong 和 Spring Cloud Gateway,看看它们在高可用架构里到底扮演什么角色。
API Gateway 在高可用中的核心职能
我习惯把网关的能力拆成三层:
- 流量入口层:统一接收客户端请求,做反向代理,隐藏后端服务细节。
- 治理策略层:限流、熔断、重试、灰度、鉴权,这些“非业务逻辑”由网关集中处理。
- 高可用保障层:健康检查、故障转移、多活路由,确保后端挂了网关还能优雅降级。
你想想看,如果每个微服务自己都维护一套限流代码,改个阈值得挨个发布。有了网关,改个配置重启一下就行。我在项目中遇到过最典型的场景:双十一流量暴涨,后端数据库扛不住。Kong 上一条限流规则,直接把读接口降到每秒 500 次,页面虽然慢但没崩。
Kong 的网关高可用设计
Kong 基于 OpenResty(Nginx + Lua),天生就擅长处理高并发。它的高可用主要靠三个设计:
- 无状态数据平面:Kong 的数据平面(Proxy)只处理请求转发,不存持久数据。挂了就挂,前面的负载均衡器会自动踢掉它。
- 控制平面与数据库分离:配置存在 PostgreSQL 或 Cassandra 里,多个 Proxy 节点共享同一份配置。配合 DB-less 模式(声明式配置),你甚至不需要数据库也能跑。
- 健康检查 + 被动探测:Kong 可以对上游服务做主动心跳检测,也能根据响应状态码做被动熔断。我曾经见过一个团队只配了主动检查,结果上游服务慢响应(200 但耗时 10 秒),流量全塞死在 Kong 上。加个被动超时探测才解决。
关键指标:Kong 单节点在 4C8G 的机器上,纯转发 QPS 能到 2 万左右。加了限流、鉴权后大概掉到 1.2 万。如果做高可用集群,建议至少 3 个节点 + 前置 Nginx 或云 ELB。
Spring Cloud Gateway 的高可用设计
Spring Cloud Gateway 是 Spring 生态里的 reactive 网关。它不走 Servlet 容器,而是用 Netty 和 WebFlux,天生异步非阻塞。
它的高可用套路跟 Kong 不太一样:
- 无状态 + 注册中心:Gateway 通常配 Eureka 或 Nacos,从注册中心动态拉取服务列表。后端服务挂了,注册中心会自动摘除,Gateway 再刷新路由就避开它。
- 本地缓存降级:注册中心挂了怎么办?SCG 可以把拉到的服务列表缓存在本地内存。我在压测时故意停掉 Eureka,Gateway 照样能转发已有服务,只是新服务不会被发现。
- 路由层熔断:配合 Spring Cloud CircuitBreaker(Resilience4j),可以在网关层直接做熔断降级。曾经有个线上事故:某支付服务响应 200 但返回“系统繁忙”的 JSON 数据,客户端错误地重试导致雪崩。我们用 SCG 的 response-body 过滤器判断 JSON 里的 code 字段,匹配到“繁忙”就返回 503 并触发熔断,问题瞬间解除。
小技巧:SCG 的路由配置支持从 Consul/Etcd 动态刷新,不需要重启。配合 Bus 做配置热更新,金丝雀发布就很方便。我一般给每个路由配一个 metadata 字段标记版本,灰度时切流量只改一个 metadata 值。
Kong vs Spring Cloud Gateway:怎么选?
| 维度 | Kong | Spring Cloud Gateway |
|---|---|---|
| 技术栈 | Nginx / OpenResty + Lua | Spring WebFlux + Netty |
| 复杂度 | 高,需单独运维数据库/DB-less | 低,Java 团队可直接整合 |
| 性能(纯转发) | 单节点 ~20K QPS | 单节点 ~10K QPS |
| 限流插件 | 内置 rate-limiting,基于 Redis/计数器 | 需集成 Resilience4j 或 Sentinel |
| 动态配置 | Admin API / DB-less 声明式 | 注册中心 / 配置中心推送 |
| 容器化友好 | Kong 原生支持 K8s Ingress | 可部署为 Deployment + Service |
我个人习惯:如果是 Java/Spring 全家桶,用 SCG 省心,不出门就能玩限流熔断;如果团队有运维和 Lua 能力,或者想用 K8s Ingress Controller,Kong 是更好的选择。
高可用部署模式:从单点到多活
无论是 Kong 还是 SCG,高可用部署的思路其实一致。我画了一张简图,方便你理解流量怎么走:
部署要点:
- 所有网关节点无状态,不存 Session
- 前端放负载均衡器(云 ELB/自建 Nginx),配健康检查:Kong 可以用 /status 端点,SCG 可以用 /actuator/health
- 配置独立存储:Kong 用 DB-less 文件或 PG 集群,SCG 用注册中心 + 配置中心
- 建议跨可用区部署,至少 2 副本
避坑指南
我曾经踩过一个坑:Kong 使用 DB-less 模式时,所有配置写在一个 YAML 文件里。因为运维同事用 scp 替换文件没注意原子性,导致半个集群读到半配置文件,部分路由失效。后来我们改用 ConfigMap 挂载 + reload 前备份,才算稳定。
SCG 也容易出问题:默认的 LoadBalancer 选择器是轮询,如果某个服务实例响应慢,轮询会一直打到它。建议配合权重或最小连接数策略。另外,Gateway 的超时设置一定要跟后端匹配,否则客户端收到的 504 会莫名其妙。
总结
API Gateway 是高可用架构的“门面”。Kong 和 Spring Cloud Gateway 都是成熟的方案,选型取决于团队技术栈和运维能力。记住一句话:网关不要成为单点,也尽量不要做业务逻辑——只做流控、路由、安全这些“公共设施”。
嗯,关于反向代理和网关,就聊到这。希望这些实战经验能帮你避开我掉过的坑。