要说微服务架构里哪个组件最容易被低估,我第一个提名 API 网关。平时开发都盯着业务代码,网关有时候到联调阶段才被想起来,真到选型的时候又常常一脸懵——网上搜“微服务网关选型”,能搜出一堆文章,但落到自己项目里,还是不知道选哪个。我这两年在大大小小几个项目里都折腾过网关选型和迁移,Spring Cloud Gateway、Kong、APISIX、Envoy、Traefik 都认真跑过,这篇就把这 5 种主流 API 网关放在一起聊:它们分别擅长什么、短板在哪、适合什么人用,以及选型之前你真正要搞清楚的那些事。适合准备搭微服务、正在做技术选型,或者觉得当前网关不好用想换的同学看。
1. 为什么你需要一个网关——选型前先想清楚的事
1.1 网关到底解决了什么问题
很多刚接触微服务的同学会有个疑问:业务代码还没写好,为什么要先关心网关?其实网关解决的问题不是“锦上添花”,而是“横切关注点”。假如没有网关,每个服务都要自己写鉴权、限流、日志、灰度逻辑,那等于把一套重复代码塞进每个业务服务里。更要命的是,外部客户端访问需要记一堆服务地址,版本灰度的时候只能人工切流量,安全策略没法统一收口。网关就是把这些东西从业务服务里“抽”出来,统一放在流量入口处理。
从请求生命周期看,网关处在客户端与后端服务之间:请求进来,先做身份认证、参数校验、限流判断,再根据路由规则转发到对应的上游服务;返回响应时再统一处理错误码、日志、链路追踪。这些功能单独拆开看都不复杂,但组合在一起,就构成了微服务架构里最关键的“门卫”。注意区分一下:负载均衡严格来说只管分发流量,而 API 网关还要做协议转换、鉴权、流控、灰度,它本质上是一个“带业务策略的流量入口”,不是单纯的 Nginx 四层转发。
1.2 选型前先列好“尺子”
我见过不少团队,选网关唯一的标准是“性能数据好看”。但你拿着别人的压测报告回来,落在自己环境里可能完全不是一回事。选型这件事,第一步不是研究网关,而是先把需求列成一把“尺子”。
第一个维度是技术栈匹配。网关不只是一个运行时组件,它还涉及维护、扩展、排障。如果一个团队主力语言是 Java,选一个主要用 Lua 写插件的网关,意味着团队里几乎没人能改插件,出了问题只能干瞪眼。反之,纯 Go 团队选 Spring Cloud Gateway 也会很别扭。第二个维度是性能预期:日均 QPS 多少、P99 延迟要求多少、长连接多不多、要不要做 WebSocket。这些指标决定了你需要的是应用级网关还是基础设施级网关。第三个维度是扩展机制:内置插件够不够,还是要自己写;写插件用什么语言;支持不支持热更新。第四个维度是运维复杂度:配置存在哪里、有没有管理界面、控制面数据面怎么部署、节点挂了怎么恢复。
建议选型之前写一个 check-list,逐项打分,而不是凭感觉“看眼缘”。后面讲到 5 种网关时,我都会按这几个维度拆,方便你对照。
1.3 选型最容易踩的三种思路
第一种是“性能参数绑架”。看到压测报告里 Envoy 吞吐第一,就非它不可。但对大多数业务系统来说,瓶颈根本不在网关这一层,数据库、缓存、下游接口慢才是主因。网关多花 2 毫秒 vs 下游超时 500 毫秒,哪个影响大,心里要有数。
第二种是“功能大而全的冲动”。网关平台化听着很高级,能多团队共用、插件齐全,但运维成本也高。一个小团队,先把核心路由和鉴权跑起来就够了,一上来就搞服务网格全套,可能还没享受到红利,先被学习曲线和运维复杂度拖垮。
第三种是“只看文档不 POC”。文档看起来完美的网关,接到真实流量后可能暴露出各种幺蛾子。后面我会专门讲 POC 怎么做,但这里先记住一个原则:候选名单不要超过两个,每套跑一周,用真实数据和体感做决定。
2. 五种主流 API 网关逐拆解
2.1 Spring Cloud Gateway——Java 微服务生态的“亲儿子”
Spring Cloud Gateway 在 Java 微服务圈子里存在感极强。它基于 Spring WebFlux 和 Netty 构建,底层是响应式编程模型,和传统 Spring MVC 的 Servlet 模型完全不同。核心抽象只有三个:Route(路由)、Predicate(断言)、Filter(过滤器)。一个请求能否命中某个路由,由 Predicate 决定;命中后经过过滤器链处理,再转发到目标服务。这种“三段式”设计很好理解。
配置上最常用的方式就是 YAML 声明式,比如给订单服务配一个路由:
spring: cloud: gateway: routes: - id: order-service uri: lb://order-service predicates: - Path=/order/** filters: - StripPrefix=1这里Path=/order/**表示匹配以/order/开头的请求,StripPrefix=1表示转发前去掉一级前缀,lb://order-service表示走负载均衡找到名为 order-service 的实例。就这几行,一个最基本的网关转发就配好了。想加鉴权,写一个 GlobalFilter 或者加一个 Auth 过滤器;想限流,可以用内置的 RequestRateLimiter 配合 Redis。整个过程对 Java 开发来说没有额外的学习负担。
这个网关的优点很明确:和 Spring Cloud 生态无缝融合,Nacos、Eureka、Sentinel 都能直接对接。团队都是 Java 的话,维护成本极低,出问题能看懂堆栈。缺点也明显:基于 JVM,内存占用比 C++ 或 Go 写得高;响应式编程让很多人踩坑,最常见的就是在 Filter 里写同步阻塞代码,结果把 Netty 线程占满。性能上它在这 5 种里不算突出,但大多数业务系统根本到不了它的瓶颈。所以如果你是 Java + Spring Boot 的团队,又没有一个专门的网关运维平台,选 Spring Cloud Gateway 基本是送分题。
2.2 Kong——老牌开源网关,插件生态很丰富
Kong 是基于 Nginx 和 OpenResty 构建的开源网关,用 Lua 写插件,诞生时间早,社区积累厚。它的核心架构是“控制面 + 数据面”:数据面就是真正转发流量的 Nginx 节点,控制面提供 Admin API,所有路由、服务、插件配置都通过 REST 接口管理,配置存储在 PostgreSQL 等数据库中。这是它和 Spring Cloud Gateway 最不一样的地方——你不是在改配置文件,而是在调用管理接口注册配置。
Kong 的几个核心概念是 Service、Route、Upstream、Consumer、Plugin。Service 对应一个上游服务,Route 是访问路径,Upstream 做负载均衡,Consumer 表示调用方,Plugin 挂载各种策略。比如给一个服务加一个限流插件,用 Admin API 就能实现:
curl -X POST http://localhost:8001/services/order-service/plugins \ --data "name=rate-limiting" \ --data "config.minute=60" \ --data "config.policy=local"这条命令的意思很清楚:给 order-service 这个服务挂上 rate-limiting 插件,每分钟最多 60 次请求。插件体系是 Kong 最值钱的部分,认证、限流、日志、转换、CORS 都有现成的,不用自己从头写。性能上,底层是 Nginx,转发效率和稳定性都很好。
但 Kong 的短板也要说清楚。最新版本的架构比早先复杂,引入了管理数据库、管理界面,部署和运维成本变高了。深度定制时还是要写 Lua,对纯 Java 或 Go 团队不友好。如果团队的技术栈是异构的(Java、Go、Node 都有),想把网关做成多团队共用的“平台”,Kong 是很稳妥的选择;如果只是 Java 内部系统,那它的优势就体现不出来,反而多了一堆要维护的组件。
2.3 Apache APISIX——云原生场景下性能和热更新很亮眼
APISIX 是 Apache 基金会下的顶级项目,底层同样基于 Nginx 和 OpenResty,但它的控制面和数据面设计更“云原生”。它支持使用 etcd 存储配置,路由匹配性能非常强,插件支持热加载,也就是说修改路由或插件配置后不用重启节点,直接生效。这一点对线上环境太重要了,你不需要再为一次路由变更专门走变更窗口。
APISIX 的核心思路和 Kong 类似,但插件机制更加灵活。除了默认的 Lua 插件,它还支持用 Java、Go、Python、Wasm 写插件,这大大降低了定制门槛——一个会 Java 的开发也能写网关插件了。内置插件覆盖了限流限速、熔断、灰度发布、CORS、WAF 等领域。配一个路由再带上限流插件,用 Admin API 就能完成:
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: your-key" -X PUT -d ' { "uri": "/order/*", "upstream": { "type": "roundrobin", "nodes": {"127.0.0.1:8080": 1} }, "plugins": { "limit-req": { "rate": 10, "burst": 20 } } }'这段配置创建了一个路由:/order/*开头的请求转发到 127.0.0.1:8080,同时挂载了 limit-req 插件,每秒允许 10 个请求,突发上限 20。配置提交后是热加载生效的,不用重启。另外 APISIX 提供官方 Dashboard,图形化操作路由和插件,对运营团队很友好。
劣势方面,APISIX 的核心仍然是 Lua,深度定制复杂场景还是绕不开;生态成熟度相比 Kong 还有差距,虽然这两年社区非常活跃,中文资料也丰富,但在某些企业级特性上,开源版和商业版之间有明显的分界。适合的场景是:对性能有要求、部署在 K8s、希望插件热更新、不想养一个庞大控制面团队的项目。如果你们已经用了 etcd,选 APISIX 会更顺。
2.4 Envoy——服务网格时代的扛把子
Envoy 这名字你可能在 Istio 里见过,它其实是 CNCF 毕业项目,用 C++ 实现的。它不是传统的“开箱即用”API 网关,更像一个高性能数据面引擎。它通过 xDS 协议动态获取路由、监听器、集群等配置,这也是服务网格里数据面的标准交互方式。它的能力非常强:负载均衡、熔断、重试、流量镜像、超时控制、观测指标都内建得很完善,性能在 5 种网关系列里属于天花板级别。
但它的“强”也意味着“重”。Envoy 的核心概念是 Listener、Cluster、Route、Filter,配置结构复杂,而且裸用 Envoy 当 API 网关时,你自己要解决控制面的问题——谁来生成配置、谁来管理版本、谁来推送。一般团队不会直接裸用,而是借助 Istio 或自研控制面来管理它。最理想的场景就是服务网格已经落地,你想把网关能力下沉到基础设施层,让业务团队低感知地接入流量治理。
如果只是几个微服务,没有引入服务网格的计划,我不建议一上来就选 Envoy。它没有开箱即用的管理界面,学习曲线陡峭,排查问题需要理解很多底层概念。你完全可以用更简单的网关解决 90% 的需求,没必要为一个还用不上的功能付出高昂的学习和运维成本。但换一个角度,如果团队已经决定走服务网格方向,那 Envoy 基本是绕不开的基石,早点接触不吃亏。
2.5 Traefik——容器原生里的轻骑兵
Traefik 是 Go 语言写的云原生网关,设计目标非常明确:“让容器里的配置更简单”。它最大的特点是自动感知:放在 Kubernetes 里,能监听 Service、Ingress、IngressRoute 等资源变化,服务一更新,网关自动重新加载配置,不需要手动改配置文件、不重启。它还自带 Dashboard 界面,能看到当前所有路由和服务状态,TLS 证书也能自动管理。对这种“放上去就能跑”的体验,用过传统 Nginx 配置的同学应该能体会到差距。
配置方式上,Traefik 支持用 CRD(IngressRoute)或 K8s Ingress 对象来定义路由。比如一个典型的 IngressRoute:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: order-web spec: entryPoints: - web routes: - match: Host(`order.example.com`) && PathPrefix(`/order`) kind: Rule services: - name: order-service port: 8080它表示:访问order.example.com/order的请求,转发到 order-service 的 8080 端口。只要这条 CRD 提交到集群,Traefik 就会自动发现并生效,这是它最迷人的地方。部署也极简单,一个 Helm Chart 就能拉起来。
但 Traefik 的短板在复杂流量治理上:限流、熔断、灰度发布这类能力,不如 APISIX 和 Kong 丰富,更多依赖外部中间件或自定义中间件。性能在极致场景下不如 Envoy、APISIX。所以它的定位很清晰:适合 K8s 环境里的中小规模服务、快速迭代的项目、团队人不多、不想花大量精力维护网关配置的场景。作为 Ingress Controller 使用,它就是那个帮你在 K8s 里快速把流量接到服务上的轻骑兵。
3. 5 种网关放在同一张桌上对比
3.1 横向对比速查表
聊完各自的特性,直接上对比表。这张表是给选型时快速定位用的,具体数据会因版本、部署方式有所差异,但方向是稳定的。
| 网关 | 核心语言 | 动态配置 | 插件生态 | 性能 | 学习曲线 | 运维成本 | 最合适场景 |
|---|---|---|---|---|---|---|---|
| Spring Cloud Gateway | Java(Reactor) | 常规配置/配置中心 | 需自行集成或编写 | 中等 | 低(Java团队) | 中 | Java 微服务 |
| Kong | Lua(Nginx内核) | Admin API / REST 动态管理 | 丰富 | 高 | 中 | 中高 | 多语言服务,平台化网关 |
| APISIX | Lua/Go/多语言 | 热更新,etcd 存储 | 丰富 | 高 | 中 | 中 | 性能敏感、K8s 部署 |
| Envoy | C++ | xDS 协议动态管理 | Filter 机制强大但需开发 | 极高 | 高 | 高 | 服务网格、基础设施层 |
| Traefik | Go | 自动感知配置源(K8s等) | 有限 | 中高 | 低 | 低 | K8s 中小规模快速上线 |
3.2 选型决策逻辑:不是“最香”,是“最合适”
每次有人问我“到底哪个最香”,我都会反问一句:你的团队平时用什么语言?你的服务跑在什么地方?你的流量到底多大?没有这些信息,任何推荐都是耍流氓。
我常用的决策路径是这样的。第一步,看不变量——团队主力语言。Java 团队优先考虑 Spring Cloud Gateway,异构团队考虑 Kong 或 APISIX,纯 Go 团队可以重点看 APISIX 或 Traefik。第二步,看存量基础设施。已经在用 K8s,且希望自动感知服务变化,Traefik 和 APISIX 都顺;已经上了 etcd,选 APISIX 成本低;已经在搞服务网格,那 Envoy 基本是必选项。第三步,看运维投入。团队里有没有专人维护网关、跑不跑得过控制面的复杂度,如果所有人都只是业务开发,那就选一个“配置越简单越好”的。第四步,看扩展预期。未来一年要不要做灰度发布、多租户、动态路由?这些需求直接决定你需要多强的插件体系。
把这四步走完,候选名单通常能缩到两个以内,然后再进入 POC 阶段。一定不要逆着团队能力去选一个看起来很先进的东西,经验告诉我,再好的网关,没人会维护,最后都会被换掉。
4. 落地实操要点与避坑记录
4.1 不管选哪个,先守住“无状态”这条底线
网关本身的实例必须做到无状态。很多人在 Spring Cloud Gateway 里做 Session 管理,或者把限流计数放在本地内存,这在单实例下没问题,一扩容就出事:用户请求打到另一台实例,Session 没了;限流数据每台各记各的,总量完全不准。正确的做法是:Session 放 Redis,限流计数走分布式组件,本地缓存只放不会导致一致性问题的数据。网关实例随时可以水平扩缩,这才符合微服务对这个入口层的预期。
另外要提醒的是,网关的配置管理一定要走“配置即代码”的路子。路由规则、插件策略、上游节点信息,这是网关最核心的资产。别直接在服务器上手工改配置文件,要么入库走版本管理,要么接配置中心或控制面管理。管理接口本身也要做好鉴权,APISIX 的 Admin API、Kong 的 Admin API 都暴露了管理能力,万一被外部访问到,相当于把整个网关的钥匙交出去了。
4.2 日志、指标、链路追踪一开始就要埋好
网关是全网请求的必经之路,这层数据非常值钱。日志要尽量结构化,建议直接用 JSON 格式,包含时间、请求路径、上游服务、响应码、耗时、traceId。指标要能直接对接监控系统,至少覆盖 QPS、P99 延迟、错误码分布、连接数。链路追踪上,网关要负责透传和生成 traceId,保证一个请求从入口到下游每个服务都能串起来。
很多项目上线后才想起来补监控,结果发现日志格式不统一、traceId 没透传、指标口径对不上,返工成本很高。我的建议是:路由和鉴权之外,第三个要配置的功能就是访问日志和指标暴露。先定好 JSON 日志字段,再定指标上报方式,最后在 POC 阶段就把链路把拉通。
4.3 压测对比的实操要点
POC 阶段一定要用真实流量或仿真流量跑压测,但压测有个容易犯的错:拿一个简化环境的数据去预测生产。压测环境至少要和生产的网络拓扑接近,否则长连接、连接复用、DNS 解析这些因素都会让数据失真。
压测时不要只看平均值,重点看 P99、P999。网关在高并发下经常出现“平均延迟很低,但尾部延迟爆炸”的情况,这直接影响用户体验。观察指标除了 QPS 和延迟,还要盯 CPU、内存、文件描述符、连接数。特别注意长连接是否复用:并发压测时如果每个请求都新建连接,网关承受的连接数压力会大很多。最后,压测结果要和团队里会运维网关的人一起分析,不要只看数字高低,要搞清楚数字背后的资源消耗和瓶颈点。
4.4 实操中的踩坑记录
第一坑:Spring Cloud Gateway 里写同步阻塞代码。很多人习惯在 Filter 里用 Feign 调用内部服务,这在 Spring WebFlux 场景下是灾难。过滤器线程是 Netty 的 IO 线程,一旦同步阻塞,整个网关的吞吐和响应都会直线下降。如果要调下游,要么改成 WebClient 异步调用,要么把同步逻辑挪到独立线程池执行。
第二坑:访问日志没裁剪。高流量下,网关的 access log 会以每分钟几个 G 的速度膨胀,几天就把磁盘写满。日志字段要按需保留,能做采样最好,定时滚动、归档、清理的机制一定要先配好。
第三坑:APISIX 配置验证太粗心。它的 Schema 校验很严格,少一个冒号都会直接报错。提交配置之前先做 validate,别直接拿线上环境试错。
第四坑:裸配 Envoy 没有控制面。很多人看了示例配置就准备上 Envoy,结果发现自己要同时维护 Listener、Cluster、Route 一堆资源的版本和关联关系,改一个上游地址得改一串配置。没有控制面管理,Envoy 的运维风险非常高。
第五坑:Kong 插件版本兼容性。升级 Kong 之前一定要先查插件支持矩阵,很多第三方插件在新版本里会失效或者行为变化,生产环境升级前先在预发环境完整跑一遍插件用例。
第六坑:Traefik 与 K8s 版本匹配。Traefik 对 K8s API 版本有要求,升级集群之前要先确认 Traefik 版本兼容性,否则 Ingress 资源可能突然不生效。
5. 常见问题与排查技巧速查
5.1 选型阶段常见问题速查表
| 问题 | 建议思路 |
|---|---|
| 团队全是 Java,选哪个? | Spring Cloud Gateway 优先,省维护成本 |
| 性能要求很高,预期 QPS 几十万 | Envoy、APISIX 方向,先压测再定 |
| 多语言服务需要统一接入 | Kong 或 APISIX,平台化管理 |
| K8s 里快速暴露服务 | Traefik 或 APISIX Ingress |
| 已经在使用 Istio | 直接考虑 Envoy / Istio Ingress,别再叠一层 |
| 想热更新路由和插件 | APISIX 优势明显,Kong 管理较复杂 |
| 团队没有专职运维 | 优先 Traefik 或 Spring Cloud Gateway,控制面越简单越好 |
5.2 运行阶段排查技巧
网关上线后,日常最常遇到的就是下面这几类问题,我整理成排查路线,方便你直接抄。
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
| 网关返回 503/504 | 上游服务未注册或健康检查失败 | 查注册中心节点状态,再查上游超时配置、负载均衡算法 |
| 限流不生效 | 插件挂错路由/服务,或数据未共享 | 确认插件作用域,检查分布式限流组件是否连接正常 |
| 请求转发到错误服务 | 路由优先级或 Predicate 匹配问题 | 打开网关调试日志,模拟请求确认命中哪条路由 |
| 内存持续上涨 | 插件有引用泄漏或大响应体缓存 | 检查插件生命周期,限制响应缓冲大小,配内存监控告警 |
| 访问日志写满磁盘 | 日志无裁剪、无采样 | 配置字段裁剪、采样率,做定时滚动归档 |
| 网关进程连接数过高 | 上游 keepalive 未开启 | 给上游配置 keepalive,压测时观察连接复用情况 |
还有一个经常被忽略的点:网关自身要配置健康检查和优雅停机。K8s 环境里 Pod 滚动更新时,如果网关实例没有优雅下线,正在处理的请求就会被掐断,用户会看到偶发 502。配合 readiness probe 和 preStop 钩子,让旧实例在停止前把存量请求处理完,这个小细节能省掉很多线上投诉。
做选型这件事,我个人的体会是:香不香真的不是参数表上的事。每个网关都有人踩坑,也有人跑得挺顺。最靠谱的做法是挑两个候选,跑一周 POC,用真实流量、真实团队成员的体感来投票,而不是光看 GitHub Star 数或者别人的压测报告。最后再分享一个细节:选型之前一定弄清楚团队未来半年到一年的规模预期。如果很明确要上服务网格,现在选 Envoy 方向就对;如果只是几个 Java 服务,直接用 Spring Cloud Gateway,别给自己加戏。网关定下来之后,把路由配置、插件规范、日志格式都文档化,后续团队再扩容,也有一条可以复用的路径。