API网关架构设计:部署模式与高可用
做API网关,我最怕听到的一句话是:「网关挂了,所有服务都访问不了。」
这不是危言耸听。网关作为流量的统一入口,一旦宕机,整个系统就瘫痪了。所以我今天想跟你聊聊,网关到底该怎么部署,才能既扛得住流量,又经得起故障。
部署模式的三种选择
先说说部署模式。不同规模的系统,选择完全不同。我见过不少团队,上来就搞多活集群,结果运维成本比业务系统还高。其实,合适才是最好的。
| 部署模式 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| 单机部署 | 开发测试、小流量场景 | 部署简单、调试方便 | 单点故障、无法扩容 |
| 集群部署 | 生产环境、中等规模 | 横向扩展、故障转移 | 需要负载均衡、配置复杂 |
| 多活部署 | 超大流量、跨机房场景 | 就近接入、极致可用性 | 成本高、数据一致性难保证 |
1. 单机部署
说白了就是一台机器跑网关。我最初做第一个网关项目时,就这么干的。调路由、配限流、测插件,都在一台机器上搞。方便是真方便,但上线后提心吊胆。机器一挂,万事皆休。
2. 集群部署
这是生产环境最通用的模式。前面挂一个负载均衡器(Nginx、HAProxy或云厂商的SLB),后面挂多个网关实例。流量分散到各个节点。
我习惯用Nginx做负载均衡,配置很简单:
upstream gateway_cluster {
server 10.0.1.1:8080 weight=5;
server 10.0.1.2:8080 weight=5;
server 10.0.1.3:8080 weight=5;
}
server {
listen 80;
location / {
proxy_pass http://gateway_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
这里有个小细节:健康检查。不加健康检查,负载均衡器会把请求打到已宕机的节点上。我见过一个项目,因为忘了配健康检查,高峰期网关某节点挂了,结果一半的请求超时。嗯,后来加了定期探测,才算安稳。
3. 多活部署
这个就高级了。比如阿里云的API网关,就是多活架构。说白了,就是在不同机房甚至不同城市都部署一套网关集群,通过DNS智能解析或全局负载均衡(GSLB)把流量分发到最近的机房。
多活的好处很明显:一个机房光缆被挖断了,流量自动切到另一个机房。但代价也不小——你得解决数据同步的问题。比如同一个用户的限流计数,在多个机房之间如何保持一致?
我建议:初期别碰多活。等你流量真到了那个量级,再考虑。
高可用的三个关键
部署模式只是第一步。真正让网关高可用的,是下面三个机制。我在项目中踩过不少坑,把它们总结出来。
1. 健康检查与自动摘除
网关实例如果挂了,负载均衡器要能自动把它踢出集群。这是基础中的基础。
通常的做法是暴露一个/health端点,返回网关自身及依赖组件的状态:
GET /health
{
"status": "UP",
"components": {
"redis": "UP",
"database": "UP",
"upstream_services": {
"user-service": "UP",
"order-service": "DEGRADED"
}
}
}
健康检查的频率很重要。我习惯设5秒一次,连续3次失败就摘除。太频繁会浪费资源,太慢又延误故障切换。
2. 无状态设计
为什么要强调无状态?因为只有无状态,才能任意水平扩展。网关实例挂了,换个新的顶上,不影响业务。
有状态的例子:把用户的校验结果缓存在本地内存里。这样节点挂了,缓存就丢了。换一个节点,又是全量校验,压力全在认证服务上。
3. 优雅关闭与热加载
网关更新配置或发布版本时,不能「一刀切」。直接关掉进程,正在处理的请求就全断了。
优雅关闭的流程:先停止接受新请求,等待正在处理的请求完成(或超时),再关闭连接。我在Nginx里用过graceful shutdown,在Kubernetes里用preStop hook实现:
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5 && /usr/sbin/nginx -s quit"]
等待5秒是为了给K8s Service一点时间,把Pod从endpoints里摘除。否则边关闭边还往里发请求,就会报错。
实战中的选型建议
讲这么多,你可能会问:我该选哪种?
我给你三个原则:
- 初创期(日均PV < 100万):单机+冷备。一台主网关,一台备用机。主挂了手动切。省钱省心。
- 成长期(日均PV 100万-1000万):集群部署,3-5个节点。加负载均衡和健康检查。这个阶段我踩过最大的坑是:健康检查只查网关自身,没查上游依赖。结果网关活着,但Redis挂了,所有限流都失效。
- 成熟期(日均PV > 1000万):考虑多活。这时候你已经有专门的运维团队了,可以搞。
架构总览
下面这张图,把今天讲的核心内容串起来了。你可以看到流量怎么进来,负载均衡怎么分发,网关集群怎么处理,以及高可用机制在哪里起作用。
总结一下今天的重点:
- 部署模式看量级,别跟风搞多活。
- 高可用的三大支柱:无状态、健康检查、优雅关闭。
- 健康检查要检得全,别只看网关自己。
- 无状态才能自由扩缩,有状态就往共享存储上搬。
我曾经在某次大促前,因为健康检查没配全,导致网关集群有一半节点虽然在运行,但连不上Redis,限流全部失效。那晚我守在监控屏前,手抖着切流。从那以后,我所有的健康检查都至少包含三个维度:自身、依赖、连通性。嗯,这都是血泪教训。