4、API网关设计:网关的作用、路由与负载均衡、限流与熔断、网关在因子工厂中的实践
4.1 网关到底解决了什么问题?
说实话,很多团队一开始觉得网关可有可无。我见过不少项目,客户端直接调后端服务,接口地址写死在代码里。刚开始还行,等服务一多,问题就全冒出来了。
网关的核心作用,说白了就三个字:统一入口。你想想看,微服务架构下可能有几十个服务,每个服务都有自己的地址和端口。客户端怎么知道该调哪个?认证怎么做?流量怎么控制?
我个人习惯把网关比作「公司的前台」。所有外部请求先到前台,前台帮你做三件事:
- 身份核验——你是谁?有没有权限?
- 引导分流——找技术部往左,找财务部往右
- 限流管控——今天来访人数太多,先排队
在因子工厂里,我们的网关承担了类似职责。它屏蔽了后端服务的复杂性,让客户端只关心业务逻辑。
- 请求路由:将外部请求转发到正确的后端服务
- 负载均衡:在多个服务实例间分发请求
- 认证鉴权:统一处理身份验证
- 限流熔断:保护后端服务不被冲垮
- 日志监控:记录所有请求的出入
4.2 路由与负载均衡——网关的「导航系统」
路由是网关最基本的功能。客户端发来一个请求 /api/factors/123,网关得知道这个请求该发给哪个服务。
我在项目中遇到过一种情况:开发同学把路由规则配错了,结果用户查询因子数据的请求,被转发到了计算服务上。嗯,那场面,接口直接返回了500。所以路由配置一定要仔细核对。
常见的路由策略有两种:
- 基于路径的路由:比如
/api/factors/**转发到 factor-service - 基于头部的路由:比如根据
X-Version头部转发到不同版本的服务
负载均衡呢?说白了就是「别让一台机器累死,其他机器闲着」。我习惯用加权轮询算法,给性能好的机器分配更多请求。
下面是一个简单的网关路由配置示例(基于 Spring Cloud Gateway):
spring:
cloud:
gateway:
routes:
- id: factor-service
uri: lb://factor-service
predicates:
- Path=/api/factors/**
filters:
- StripPrefix=1
- id: calculation-service
uri: lb://calculation-service
predicates:
- Path=/api/calculate/**
filters:
- StripPrefix=1
你看,lb:// 前缀就表示启用负载均衡。网关会自动从注册中心获取服务实例列表,然后轮询分发请求。
4.3 限流与熔断——网关的「安全气囊」
为什么需要限流?我曾经遇到过线上事故:某个大客户的数据同步脚本写了个死循环,每秒发几万个请求过来。如果没有限流,整个系统直接瘫痪。
限流的常见算法有:
| 算法 | 原理 | 适用场景 |
|---|---|---|
| 令牌桶 | 以固定速率往桶里放令牌,请求来了拿令牌 | 允许突发流量 |
| 漏桶 | 请求以固定速率流出,超出则丢弃 | 平滑流量 |
| 滑动窗口 | 统计时间窗口内的请求数 | 精确控制 |
我个人习惯用令牌桶算法。为什么呢?因为它允许一定的突发流量,不会把正常的业务高峰给误杀了。
熔断呢?它和限流是两回事。限流是主动控制,熔断是被动保护。当某个后端服务频繁超时或报错时,网关会直接切断对这个服务的调用,快速返回降级响应。
熔断器的三种状态:
- 关闭:正常调用,统计失败率
- 打开:失败率超阈值,直接拒绝请求
- 半开:过一段时间后,放少量请求试探服务是否恢复
4.4 网关在因子工厂中的实践
在因子工厂项目中,我们用的是 Kong 作为 API 网关。为什么选它?因为性能好,插件生态丰富,而且支持热加载配置。
我们的网关架构大致是这样的:
具体实践中,我们做了几件事:
- 统一认证:所有请求先经过网关的 JWT 插件校验,合法才放行。这样每个服务都不用自己写认证逻辑。
- 细粒度限流:对不同的客户端设置不同的限流阈值。VIP 客户每秒可以调 1000 次,普通客户只能调 100 次。
- 灰度发布:通过网关的路由规则,把 10% 的流量引到新版本服务上,观察没问题再全量切换。
嗯,这里要注意一点:网关不要承载太多业务逻辑。我见过有人把数据转换、业务校验都塞到网关里,结果网关变得又重又慢。记住,网关只做「转发」和「管控」,业务逻辑留给后端服务。
最后说一句,网关的选型没有银弹。Kong、Zuul、Spring Cloud Gateway、Nginx 各有优劣。关键看你的团队熟悉什么技术栈,以及业务场景需要什么能力。在因子工厂里,我们选 Kong 是因为它插件丰富,开箱即用,省去了很多自研的功夫。