API 网关概述:定义、作用与常见产品

API 网关这东西,说白了就是微服务架构的“前门”。所有外部请求都得先过它这道坎,再由它决定去哪个后端服务走一趟。我入行那会儿,团队里还在用裸 Nginx 配上游转发,后来服务一多,光路由规则就写了上百行——嗯,从那以后我就知道,该上个正经网关产品了。

到底什么是 API 网关?

按我的理解,API 网关是一个位于客户端和后端服务之间的中间层,统一处理所有 API 请求的进入、路由、过滤和响应。它承担了几件事:

  • 统一入口:客户端只认一个地址,不用记几十个服务域名。
  • 请求路由:根据路径、方法、Header 把请求转发到对应微服务。
  • 横切关注点:认证、限流、日志、熔断——这些逻辑不用在每个服务里重写。
  • 协议转换:比如把外部 HTTP/1.1 转成内部 gRPC,或者把 RESTful 转成 WebSocket。
我的一点经验:在早期项目里,我习惯让网关只做“路由+认证”,其他逻辑尽量后置到服务层。因为网关一旦挂了,整个系统就断了——轻装上阵,出问题好排查。

为什么需要它?

你想想看,没有网关的时候,客户端要自己知道所有服务地址,还得单独处理每个服务的认证逻辑。这压根不现实。我记得有一次帮一个团队重构,他们前端直接硬编码了十几个 IP:Port,上线那天改了三个服务的地址——结果前端漏更新了,线上故障半小时。这就是典型的缺乏网关的痛点。

网关带来的核心价值,我列了个表:

维度 无网关 有网关
服务发现 客户端或 Nginx 手动维护列表 网关自动从注册中心拉取
认证授权 每个服务重复实现 网关统一拦截,支持插件化
限流熔断 要么不做,要么在每个服务里写 网关集中配置,按路由精细控制
监控日志 分散存储,排查困难 网关统一输出,链路追踪也方便

一句话总结:网关不是中间件,而是微服务架构的“战术指挥点”。我倾向于把它看成架构策略的执行面,而不是单纯的流量代理。

常见网关产品一览

市面上的网关产品不少,我个人接触最多的就是 Kong、APISIX 和 Zuul。下面逐个聊聊它们的特长和适用场景。

Kong

Kong 是基于 OpenResty(Nginx + Lua)的网关。它最大的特点就是插件生态丰富——官方和社区加起来几百个插件,从基本的路由、限流到复杂的 OAuth2、GraphQL 都能找到现成的。我之前有个项目需要快速集成 JWT 验证和 IP 黑白名单,半小时就配好了 Kong 的声明式配置:

# 一个简单的 Kong 声明式路由
services:
  - name: user-service
    url: http://user-svc:8080
    routes:
      - name: user-route
        paths:
          - /api/users
        methods: [GET, POST]
        strip_path: false
    plugins:
      - name: jwt
        config:
          secret: my-jwt-secret
      - name: rate-limiting
        config:
          minute: 60

用起来是真的爽,不过要注意它的数据存储依赖 PostgreSQL,部署时得额外维护一个数据库。嗯,小项目可以接受,大集群里就要考虑读写性能了。

曾经踩过的坑:有一次我图省事直接用 Kong 的默认配置跑在单机上,结果插件太多把 Lua 虚拟机撑爆了。后来才意识到,每一个请求都会加载所有插件的 Lua 字节码 —— 所以生产环境里一定要按需启用插件,别一股脑全开。

APISIX

APISIX 是 Apache 基金会的顶级项目,也是 OpenResty 系的后来者。它的亮点在于 动态路由 和 热更新 —— 路由、上游、插件全都可以通过 Admin API 实时添加,无需 reload。我记得给一家电商做压测时,APISIX 单核能扛 2 万多 QPS,延迟只有几毫秒。它的声明式配置长得跟 Kong 类似:

# APISIX 路由示例(Admin API 直接创建)
curl http://127.0.0.1:9180/apisix/admin/routes \
  -X PUT -d '{
    "uri": "/api/orders/*",
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "order-svc:8080": 1
      }
    },
    "plugins": {
      "limit-count": {
        "count": 200,
        "time_window": 60
      }
    }
  }'

特别适合需要频繁变更路由或灰度发布的场景。它内置的 WAF 插件也够用,很多用户直接用 APISIX 把 Nginx 配上的 OpenResty 全给替代了。

Zuul

Zuul 是 Netflix 开源的 Java 网关,老牌 Spring Cloud 生态标配。虽然现在 Netflix 自己都不怎么维护了,但国内很多传统企业还在用。它的强项是深度集成 Eureka 和 Ribbon,适合 Java 技术栈的历史项目。但性能上跟 Nginx 系差距明显——我曾经见过一个 Zuul 1.x 的网关,单线程处理 IO,并发上来立刻瓶颈。Zuul 2.x 虽然换成了 Netty,但生态和社区热度远不如 APISIX 和 Kong。

我的选型建议:Java 团队且服务规模不大,用 Zuul 可以省去学 Lua/Python 的成本;追求高并发和灵活插件,直接上 APISIX;需要开箱即用的插件市场,Kong 是稳妥之选。没有的好坏,全看实际约束。

一张图看清核心逻辑

下面这张图展示了 API 网关在微服务中的定位,以及横切关注点的处理流程。我专门把“策略即代码”的雏形也画进去了——因为从网关开始,策略就不再是写在代码里的硬逻辑,而是可以声明式配置、动态加载的独立单元。

API 网关核心流程图 客户端请求 路由 / 负载均衡 认证 / 限流 / 日志 协议转换 / 熔断 策略即代码 声明式配置 动态加载 热更新 可版本化管理 微服务 A 微服务 B

从图中你能看到,请求先经过路由层,再到认证/限流层,最后经过协议转换层才抵达后端服务。而右侧的“策略即代码”框代表我后面章节会深入的主题——这些横切逻辑不再需要硬编码在服务内部,而是可以被当作独立配置单元统一管理。

小结:网关是架构演进的必然产物