你的团队,到什么规模才需要 API Gateway?

大多数团队上 API Gateway,上早了。网关解决的是规模问题——在服务数、客户端类型、团队数这三个变量同时增长之前,它带来的隐性成本远大于收益。一套 S×C×T 决策矩阵帮你判断临界点。

封面

大多数团队上 API Gateway,上早了。

我不是在反对网关。我是说,你大概率在错误的规模上做了这个决定。网关解决的是一个真实问题,但它解决的问题,只在长到某个临界点之后才出现。在这之前,它只是你花钱养着、会挂、还要专人盯的额外组件。

讲个真事(缩影,以下团队和人名为虚构)。2021 年初,「明远」是一家做 B2B SaaS 的创业公司,后端 5 个人。他们把运行了一年的单体拆成 6 个微服务,顺手上了 Kong。「微服务最佳实践」里几乎每篇都在讲网关是标配,技术负责人老周觉得迟早要上,早点上省得返工。他后来复盘,当时根本没算过「上了之后要付出什么」,只是怕「别人都有、我没有」。用他的话说,「那时候上网关不是为了解决问题,是为了不显得落后。」

半年后他跟我说:那半年里,Kong 从 2.x 升 3.x 卡了两周,鉴权插件 API 不兼容,每次改动都要回归全部 6 个服务;一次限流配置被误写成全局 10 QPS,支付接口直接被拦在门外;还有一次网关节点 OOM,全站流量被挡在门外。他后来算了笔账:6 个服务各自写一遍 JWT 校验,总共 300 行重复代码,为了管这 300 行,他们引入了一个需要专人盯的组件。

老周的问题不是「该不该上网关」,是「在我只有 6 个服务、只有一套 Web 前端的时候,我为什么要上网关」。这篇文章想回答的,就是这个问题:你到底长到什么规模,才真的需要它。

一、网关不是免费的

「微服务就该有 API Gateway」这句话,据我观察已经成了一种肌肉记忆。很多团队做架构评审,网关是默认勾选项,没人问为什么。但凡你把它从默认项里拿出来问一句「不上会怎样」,往往答不上来。我参加过不少架构评审,网关那一项几乎从不被挑战。有人问过「我们真的需要吗」,话音没落就被「业界都这么干」堵回去了。这种沉默本身就是信号:决定不是想清楚做的,是跟着别人做的。

网关确实能做事。统一鉴权、限流、灰度、审计、协议转换,这些横切关注点它都能接管。问题是,这些能力不是白给的。每加一层,你都在付一笔隐性成本。

隐性成本叠加示意

第一笔是延迟。 网关是流量必须经过的一跳。哪怕它只做鉴权转发,也会在你的调用链路上多加几毫秒的 RT,P99 更明显。单看不觉得,但当你的链路已经串了五六个服务,每一跳都在叠加,网关是其中无法省略的一跳。我见过一个内部接口(缩影,非实测),服务间直调本来 2 毫秒,套了网关做鉴权后变成 5 毫秒。单次无所谓,但当你的请求要串过六七个服务,每一跳都多 3 毫秒,末端就比直连慢了小二毫秒。补一句:内部服务之间的调用本不该每跳都过入口网关(那是服务网格解决的东西向流量),这个例子只是说明「网关加一跳就加 RT」的方向,别当成普遍延迟定论。用户未必感知得到,但你的 P99 曲线会记下来。

第二笔是故障域。 单体时代一个服务挂了,顶多那个功能不可用。引入网关之后,网关挂了,是所有外部请求都进不来。

它从「帮你做事的组件」变成了「决定你能不能营业的组件」。故障域不降反升。

老周那次 OOM,不是网关代码有 bug,是连接池没随流量调。一个本该只在网关团队内部消化的配置疏忽,最后让全站停摆。这就是故障域扩大的本质:你把系统的生死,系在了一个原本只想让它「帮忙」的组件上。

第三笔是配置漂移。 网关有自己的配置面:路由、插件、限流规则、证书。这套东西和你的服务部署、K8s 清单是分离的。

老周那次线上事故,根因不是代码写错,是「又多了一套要和服务部署保持同步的配置」。配置面每多一套,就多一处可能出错的面。

服务本身的配置已经在 K8s 里了,网关又来一套独立的。两套各自演进,迟早不一致。老周那次 10 QPS 的事故,就是网关的配置仓库和服务的部署清单各管各的,发布时没人把两边对齐。

第四笔是版本耦合。 网关升级,往往要回归所有走它的服务。Kong 2.x 到 3.x 那次,就是插件 API 不兼容逼着老周改了一圈。你以为上的是个独立组件,实际上它的版本节拍会牵动整条链路。网关一升级,所有依赖它鉴权插件、限流规则的服务都要跟着回归。你以为是升个中间件,实际是给整条链路排了一次期。团队小的时候,这个成本摊不薄。

有人会反驳:现代 API Gateway 设计得当,根本不会成为瓶颈,也不会是单点。这话对,但没用。对,是因为它描述的是「理想状态下的网关」;没用,是因为绝大多数团队不是设计得当,而是把网关当成「上了就完事」的免思考银弹。这里有个容易绕进去的弯:设计得当,本来就意味着你已经把专人盯、CI 管限流和证书、升级有回滚预案这笔运维算进去了。换句话说,设计得当的团队,上的那一刻就已经付了运维的钱。我反对的不是设计得当的网关,而是「错误规模 + 不上心」:小团队在只有 6 个服务、一种客户端时,根本没打算付这笔账,却先把网关请进了门。真正拖垮团队的不是网关的技术上限,是它带来的、本以为不用付的运维负担和认知负担。

顺便聊几个我常看到的误区。

误区一,把网关当服务拆分的解药。网关管的是「入口」,拆服务解决的是「内部耦合」,这是两件事。服务拆得烂,上网关只会让烂更有序地暴露,不会让烂消失。

误区二,以为上了网关就不用管鉴权细节。网关做统一鉴权,但每个服务仍要知道「我是谁、我能干什么」,这部分逻辑不会因为有了网关就蒸发。

误区三,拿大厂架构当自己的起点。大厂几十个服务、多端、多团队,网关是刚需;你三个服务一个 Web,照抄就是给自己找运维。

我翻过 Kong、APISIX、Envoy 几家主流网关的官方文档(Authentication、Rate Limiting 等章节),它们把「网关能做什么」讲得很清楚:路由、鉴权、限流、可观测。但没有任何一份文档会告诉你,为了这些能力,你每年要付出大约半到一个人月的运维,以及一个新的故障域和配置面。文档负责让你心动,运维成本得你自己算。它们不会写「本组件需专人值守」,不会写「升级时请预留两周回归窗口」,更不会写「配置面与主部署分离后请自行保证同步」。这些字,只出现在你凌晨被告警叫醒的脑子里。

那不是小团队永远别碰网关?不是。我反对的是「默认勾选」,不是「永远不用」。如果你只有 4 个服务,但明天要接三个外部合作方,客户端类型这一维已经亮了,该上就上。规模是多维的,别被服务数一个数绑架。

所以反共识的结论很朴素:在小规模时,网关省下的那点重复代码,远抵不过它带来的运维和事故成本。它不是免费的,它是一张按月扣费的账单。

按月扣费的账单

二、网关是长出来的,不是设计出来的

老周两次上网关对比

回到老周的故事后半段。2022 年中,「明远」服务数长到 30 多个,前端也多了商家 App 和开放 API 两个外部客户端。第一次上网关时他图省事,配置、监控、告警都没认真做;第二次他专门分了人盯网关,限流规则和证书管理进了 CI,升级有回滚预案。同样是上网关,第二次顺理成章,再没踩过第一次那些坑。他的原话是:「第一次上,是怕落后;第二次上,是因为疼了,而且这次我知道疼在哪。」

这就是关键:网关不是你画架构图时预先决定的,是规模把它逼出来的。老周的故事说明了一个朴素的道理:痛过的人才知道怎么用,只有被规模教育过,才会认真对待网关的运维和治理。

我习惯用一个演进阶梯来看这件事,每一级都有它自己的触发信号。不过阶梯是参考顺序,不是必经路径。信号没来,不必逐级走过。比如单服务但已经有第二种客户端,BFF 的需求可能比 L1 的反代更早亮。

演进阶梯

L0 单体直连。 只有一个服务,或一个服务带几个模块。这时候你连反向代理都不一定需要,顶多一个 Nginx 做静态和 TLS 终结。触发信号:无,别想太多。信号没来时你硬上 L2 的 BFF,等于给一条还没分叉的路提前修建交桥,修完发现没人走。

L1 反向代理。 拆出多个服务,但客户端类型单一(只有 Web 后台)。Nginx 或轻量网关做路由转发就够了,鉴权在每个服务里各写一遍,几十行,不痛。触发信号:服务数变多,但客户端只有一种,路由需求出现了。一个真实的触发:你发现前端要同时调订单、用户、商品三个服务才能拼成一个页面,每个页面都重复这套调用编排,路由和聚合的需求就冒头了。信号没来时硬上 L3 全功能网关,就是老周第一次的故事。

L2 BFF(Backend for Frontend)。 出现第二种客户端类型(Web 之外多了 App,或外部合作方要调你的接口),不同端对聚合、字段裁剪的需求不一样。这时候上 BFF(可由轻量网关承载,也可独立成服务),按端拆分聚合逻辑,比让每个服务去适配所有端更干净。触发信号:客户端类型 ≥ 2,且各端的数据聚合需求明显不同。信号没来时(还只有一种客户端)硬上 L3,多端适配的能力你用不上几成,版本耦合先吃满。

L3 全功能网关。 服务数 15+,客户端类型多,团队也拆成了多个,统一的鉴权、限流、灰度、审计变成刚需,而且有人愿意专职运维它。触发信号:重复的横切代码已经肉眼可见地拖慢迭代,且多团队需要一致的入口治理。

举个越级的例子:你在 L1(单一 Web、6 个服务)就按 L3 上全功能网关,结果就是老周的故事,能力用不上几成,运维成本先吃满。反过来,你在 L2(Web 加 App 双端)还死守 Nginx 反代,每个端各自调所有服务,聚合逻辑散落在前端,改一个字段要发两个端。信号其实早就亮了,只是你没看。到了 L3 你才会懂,那些在 L1 用不上的灰度、审计、多租户限流,此刻每一个都恰到好处。

注意,这个阶梯里没有「该不该」,只有「信号来了没有」。很多人犯的错,是在 L1 的体量上,按 L3 的最佳实践去部署网关。架构不是越完整越好,是越匹配当前规模越好。

信号判断标尺

那怎么判断信号真来了?我给自己两条朴素的标准。一是「同样的事开始做第三遍」:第三个服务又在写一遍鉴权,第三个端又在调一遍聚合,重复本身在告诉你要收口了。二是「出事的成本开始大于不出事的成本」:某次配置失误的代价,已经高于养一个网关的代价。满足任一条,再上,不亏。

微软的 API Gateway 模式文档中也承认,客户端直连微服务的痛点在于「端点爆炸」和「前端要适配每个服务的接口形态」。这个判断我同意,但它同样没回答规模问题:端点爆炸在 3 个服务时不叫爆炸,在 30 个服务时才真的痛。模式文档描述的是终态,而你大概率还在起点。

三、一张决策矩阵,替你判断

讲到这里,你需要的不是更多道理,是一个能自己用的判断工具。我把「规模」拆成三个可数的变量,你照着填,答案自己出来。

决策矩阵 S×C×T

  • S:后端服务数
  • C:外部客户端类型数(Web、App、开放 API、第三方合作方,各算一种)
  • T:维护这些服务的团队数

判定规则:

条件 结论
S < 8 且 C = 1 不上。Nginx 反代 + 各服务轻量中间件足够,网关是净负担
S ≥ 8 或 C ≥ 2 开始考虑 BFF 或轻量入口治理,先解决「聚合」和「多端适配」
S ≥ 15 且 C ≥ 2 且 T ≥ 2 上全功能网关,此时运维成本被规模摊薄,值回票价

补充一条:如果因为 SOC2、等保、PCI-DSS 这类合规要求必须统一入口,那跟规模无关,该上就上。这是另一条独立的驱动线,不是规模信号。

套几个真实的画像(缩影)试试:

  • 画像甲:8 人团队,4 个服务,只有 Web。S 小于 8 且 C 等于 1 → 别上。Nginx 反代足够,你省下的是一个本不会发生的故障域。
  • 画像乙:12 人,10 个服务,Web 加一个合作方 API。S 不小于 8 或 C 不小于 2 → 上 BFF。先解决「合作方要的数据和 Web 长得不一样」这件事,别让合作方直接啃你的内部接口。
  • 画像丙:40 人,25 个服务,Web 加 App 加开放平台,3 个团队。三项全满足 → 上全功能网关,专人运维,这时它的运维成本被规模摊薄,真的值。
  • 画像丁:15 人,14 个服务,但只有 Web。S 接近 15,C 仍为 1。我的建议是:先别上全功能网关,但把鉴权收拢到一个共享库,等第二个客户端类型出现再升级。服务数到了,可客户端没到,信号只亮了一半。

为什么是这个阈值?我做个量级推演(非实测,下面是工程常识的合理估算,别当成精确公式)。拆开看:每个服务自写鉴权约 50 行、限流约 40 行,只算这两项约 90 行;把审计、灰度也算上,约 150 行。网关一次性接入约 300 行配置,外加半到一个月的首次上线。单看鉴权:6 个服务自写 300 行,和网关接入的 300 行刚好打平;可一旦加上限流和每年 0.5 到 1.5 人月的运维(按人力 2 到 4 万粗略计,每年约 1 到 6 万摊在头上),打平点就被推到 8 到 10 个服务。按 150 行口径更直观:服务数到 8 到 10 个时,自写累计到 1200 到 1500 行,自写的麻烦才真正超过养网关的花费。这就是「右移」:交叉点不在 6,在 10 上下。不过这是经验线,不是物理定律:矩阵给的是方向,≥8 进入观察区,约 10 才净正,它不催你立刻到。

成本曲线与交叉点

把限流、审计、灰度都算上,每个服务重复代码上探到约 150 行,服务数 8 到 10 个时,自写总成本开始明显超过网关的接入加首年运维。但这只是「代码重复」一个维度。真正让网关早早就在 L2 就值得引入的,是 C(客户端类型),一旦你有两种以上的外部调用方,入口治理的复杂度比单纯服务数增长得快得多,这时候 BFF 或轻网关的回报就出来了。为什么 C 比 S 更敏感?因为 S 增长,你只是重复写代码,痛苦是线性的;C 增长,每个端要的数据形状不同,痛苦是指数级的——Web 要的字段、App 要的字段、开放 API 要的字段,三套聚合逻辑会迅速把你淹没。

所以矩阵的精髓不是「S 到多少」,是三个变量合起来看。一个 20 人的团队、3 个服务、1 套 Web,我劝你别上;一个 5 人的团队、12 个服务、Web 加 App 加开放 API,你现在就该上。规模不看人头,看「服务数 × 客户端类型 × 团队数」这个乘积。

如果你卡在中间档(比如服务数到了 15),但客户端还只有一种,别急着上全功能网关。先做轻量的 BFF 或反向代理,把「聚合」和「多端」的问题解决掉,等客户端类型也来了,再升级到全功能。矩阵给的是方向,不是非黑即白的开关;它告诉你往哪走,不催你立刻到。

如果你已经上了,但对照矩阵发现其实不该上。别慌,也别为了「架构纯粹」立刻拆。先收缩网关的职责:把灰度、审计这些重能力关掉,只留路由和鉴权,把它当个瘦反向代理用着,等规模真到了再补齐。架构债不是靠推倒重来还的,是靠降级和等待还的。

几个常被问到的问题:

用了服务网格(Service Mesh)还要网关吗? 要。网格管的是服务与服务之间,网关管的是外部与你的服务之间,两件事。网格不替代网关,它只是把服务间那层你自己写的鉴权、重试、熔断接走了。

云厂商的托管网关是不是更省心? 省了运维节点,但绑定和费用换了一种形式,规模的判断逻辑一点没变。你只是把「养人」换成了「付账单」。

网关和 BFF 什么关系? BFF(Backend for Frontend)是独立的按端聚合后端层,不是网关的一种用法。它可以由轻量网关承载,也可以由独立服务承载,二者是「承载方式」的关系,不是「包含」关系。你可以在 L2 用轻量网关做 BFF 聚合,也可以在 L3 让全功能网关顺带承载 BFF 逻辑。

最后提醒一句:网关插件(Kong/APISIX 的 Lua、Envoy 的 xDS)会带来厂商锁定和技术栈耦合,这是选型时要算进来的长期隐性成本,但判断逻辑不变,还是看规模信号。

四、带走这张表

把全文收成一张你能贴在工位上的速查表:

你的现状 建议
服务少(<8)、一种客户端 别上。反代 + 各服务轻量中间件
服务多了,或多种客户端 上 BFF / 轻量入口治理,先解决聚合
服务 15+、多客户端、多团队 上全功能网关,专人运维

决策速查表

回到开头老周的那句话:网关是被规模逼出来的,不是设计出来的。你问「要不要做 API Gateway」,这个问题本身问错了。正确的问法是:我的服务数、客户端类型、团队数,乘积到那个临界点了吗?

如果没到,你现在省下的不是一个组件,是半个人年的运维和一堆本不会发生的事故。如果到了,那它早该上了,你只是在补债。

以上是我的判断,基于几个缩影案例和量级推演。你的规模线可能和我的经验线不同,但判断的方法是一致的:别问「该不该」,问「信号来了没有」。

这篇文章没教你部署网关,因为那不是你的问题;它只教你判断要不要,因为那才是。

我写这篇文章的初衷,是希望下次有人问你「要不要上 API Gateway」时,你能多问一句:我的服务数、客户端类型、团队数,三个变量一起看,到了哪个位置?而不是条件反射地说「先上个网关」。技术选型最怕的不是选错,是没想清楚就选——大多数网关引入的案例,问题恰恰出在「没想清楚」,不是「网关不好」。

如果你还在犹豫,记住三个临界点:服务数到 8 时停下来问自己一次,客户端类型超过 1 种时再问自己一次,团队超过 1 个时认真算一次账。这三个时点,比你记忆中任何「最佳实践」都更靠得住。

原文发布于 止语Lab

收尾书挡


关于止语Lab

一个工程师的深度技术笔记。

不写入门教程,不追热点。只写那些真正折腾过、想通了的东西。

了解更多 →