网关责任先拆清

网关一开始通常只是入口:收请求、转服务、打日志。随着系统变大,认证、鉴权、限流、灰度、熔断、协议转换、参数校验都开始往网关里放。再过一段时间,网关甚至开始判断业务状态、补默认参数、拼装响应。等它变慢或变复杂时,团队才发现入口已经成了另一个业务系统。
我不反对网关承担重要职责,但要先拆清它到底负责什么。网关适合做横切能力,尤其是入口安全、流量治理、路由和观测;不适合承接具体业务编排,更不适合把下游服务应该表达的业务规则藏在入口层。
先画一张责任地图
做网关治理时,最好不要从“加不加这个功能”开始争,而是先画责任地图。横向列出入口安全、协议适配、流量治理、服务路由、可观测性、业务规则、数据编排,纵向标出哪些应该在网关,哪些应该在下游,哪些需要专门的编排层。
这张图不一定一次就正确,但它能让讨论从口味变成边界。比如参数签名校验放网关比较合理,因为它和入口安全有关;订单是否允许取消就不适合放网关,因为它依赖订单状态、支付状态、履约状态和业务规则。
如果某段逻辑离开具体业务后仍然成立,它更可能属于网关。如果它必须理解某个领域对象,最好别长期放在网关里。这个判断虽然简单,却能挡住很多“顺手写一下”的债务。
网关适合横切能力,不适合吞掉业务语义。
认证和鉴权不要混成一团
认证回答“你是谁”,鉴权回答“你能不能做这件事”。两者常常挤在同一段网关逻辑里,短期省事,长期会让权限问题很难追。用户身份解析可以在网关统一做,但业务资源级别的判断未必都适合放在网关。
比如订单详情能不能看,往往需要订单归属、组织关系、数据范围和订单状态。网关如果只靠 token 和路径判断,很容易误放或误拦。更稳的方式是网关做身份和粗粒度权限,下游服务做资源级判断。
这不是把责任推给下游,而是让权限判断靠近资源。越靠近资源,越能拿到完整上下文;越靠近入口,越适合做统一、安全、低成本的拦截。
限流要按风险分层
所有接口共用一个限流策略,看起来简单,实际很粗暴。登录、搜索、支付、导出、回调、静态查询的风险和成本都不一样。网关限流应该至少区分用户、接口、来源和下游成本。
低成本查询可以更宽松,高成本导出要更严格;匿名流量和登录用户不能一样;内部系统和公网入口也不能一样。策略分层以后,告警也更容易解释:到底是某个用户打爆了,还是某类接口设计有问题。
限流不是为了让请求失败,而是为了保护系统有序退让。因此响应文案、重试建议和监控指标也要配套。只有一个 429,很难帮助业务判断是否需要扩容、降级还是封禁。
路由和灰度要有版本意识
网关做灰度很常见,但灰度不是简单把 5% 流量打到新服务。用户粘性、接口版本、Header 标记、回滚路径、缓存命中都会影响结果。灰度路由必须记录命中规则,否则出问题时无法解释某个用户为什么进了新版本。
我会把灰度规则拆成三个部分:人群选择、服务版本、回滚开关。人群选择负责谁进灰度,服务版本负责去哪里,回滚开关负责出问题时如何撤回。三个点混在一个配置里,会让回滚动作很笨重。
还要避免网关替业务判断过多状态。灰度入口只决定流向,具体业务兼容仍然要由服务自身保证。否则网关配置会越来越像业务规则表。
灰度要能解释命中原因和回滚路径。
下面这段不是让你照抄,而是把边界写成团队能讨论的形式:
  1. 入口责任 = 身份解析 + 粗粒度权限 + 流量治理 + 路由观测
  2. 业务责任 = 资源判断 + 领域规则 + 数据编排 + 结果语义
  3. 编排责任 = 多服务组合 + 业务流程推进 + 失败补偿
text
错误语义不要被网关吞掉
很多网关改造会顺手统一错误码。统一格式是好事,但不能把下游语义抹平。库存不足、权限不足、参数错误、依赖超时、服务降级,给前端和业务系统的含义完全不同。如果网关全部改成“系统繁忙”,排查会变慢,用户体验也会变粗糙。
我更倾向于网关统一外壳,下游保留原因。比如响应格式、traceId、时间戳可以统一;错误类型和业务原因要可透传、可映射、可审计。对于敏感错误,可以在对外文案上收敛,但内部日志里必须留住真实原因。
网关还要区分自身错误和下游错误。入口鉴权失败、限流命中、路由不存在,这是网关责任;库存服务超时、订单状态冲突,是下游责任。责任分清以后,告警才能打给正确的人。
观测字段要少但稳定
网关最适合沉淀入口观测:traceId、用户标识、来源、路由结果、限流结果、耗时、下游状态。这些字段不需要很多,但必须稳定。字段一旦稳定,排查就能从入口一路追到下游。
不要把所有请求体都打进日志,也不要把业务隐私字段放在网关日志里。好的观测是能定位链路,而不是复制一份业务数据。尤其是高并发接口,日志字段越克制,越能长期保留。
网关指标也要区分维度。总 QPS、总错误率只能说明入口状态;按服务、接口、来源、人群拆开,才能定位哪一段出了问题。比如错误率上升,如果只看总数,你不知道是新版本灰度出问题,还是某个来源流量异常。
配置变更必须能审计
网关一旦承担路由、限流和灰度,配置就等于线上逻辑。谁改了规则,为什么改,影响哪些接口,什么时候生效,如何回滚,都要留下记录。没有审计的网关配置,迟早会变成“线上和文档不一致”的现场。
配置发布最好有预览能力。比如某条灰度规则上线前,能看到命中用户范围、影响接口、预期下游;限流规则上线前,能估算过去一天会拦截多少请求。不是每个团队都要做完整平台,但至少不能让配置靠手感生效。
回滚也要一键化。网关规则通常影响面大,出问题时不适合靠人工慢慢改字段。真正需要演练的不是“我会改配置”,而是“我能在一分钟内恢复旧规则,并且知道恢复后会发生什么”。
越靠业务语义,越不应该长期放在入口层。
什么时候需要编排服务
当网关里出现大量“先查 A,再查 B,然后根据 C 拼结果”的逻辑时,应该考虑把它挪到编排服务。编排服务可以理解业务流程,网关保留入口能力。这样做不是为了多加一层,而是为了让每一层承担自己能解释的责任。
判断标准可以很具体:这段逻辑是否需要事务或补偿;是否依赖领域模型;是否会被多个入口复用;是否需要独立测试;是否会随着业务策略频繁变化。如果答案多数为是,就不要再让网关继续膨胀。
最后的落地建议很简单:先盘点网关现有逻辑,按横切能力、业务语义、临时兼容三类归档。横切能力留下,业务语义迁移,临时兼容标注下线时间。网关不是不能复杂,但它的复杂度必须来自入口治理,而不是业务边界失守。
兼容逻辑要有下线日期
网关里最容易长出一类逻辑:临时兼容。某个老客户端没带新 Header,网关先补一下;某个下游接口字段改名,网关先转一下;某次活动要特殊路由,网关先写一条规则。每一条看起来都合理,但如果没有下线日期,它们会一直留在入口层。
兼容逻辑的问题在于,它通常既不像正式能力那样有完整设计,也不像临时脚本那样用完即删。过几个月以后,新同学看到这段配置,很难判断它还能不能删。为了安全,他会选择继续保留。于是网关越来越厚,真正的入口治理反而被埋在一堆历史兼容里。
比较实用的做法是给兼容规则加三个字段:来源、影响范围、计划下线时间。来源说明为什么加;影响范围说明会命中哪些客户端或接口;下线时间提醒团队回收。哪怕不能自动删除,至少让规则从“没人敢动”变成“知道该什么时候复查”。
协议转换不要变成业务翻译
网关做协议转换很正常,比如 HTTP gRPC,外部字段到内部字段,移动端版本到后端版本。但协议转换和业务翻译只隔一条很细的线。把 user_id 转成 userId 是协议转换;根据用户等级把某个字段改成另一种含义,就是业务翻译。
业务翻译放在网关里,最麻烦的是上下游都看不见真实语义。前端以为是后端返回,下游以为是原始请求,中间网关偷偷改了规则。排查时大家都看自己的系统,谁也找不到完整答案。
如果必须在网关做转换,就要限制在格式、版本、传输协议层面,并记录转换前后的关键字段。涉及业务含义的转换,应该推回服务层或编排层。入口层可以帮忙过桥,但不应该重新定义桥两边的道路。
压测要覆盖网关自己的成本
很多团队压测只看下游服务,忽略了网关本身。可当网关承担签名校验、动态路由、限流、日志、指标和协议转换后,它也会消耗 CPU、内存和连接池。下游没满,网关先满,并不罕见。
网关压测要分开看三类成本:纯转发成本、策略命中成本、异常路径成本。纯转发看入口吞吐;策略命中看限流、鉴权、灰度规则的计算开销;异常路径看大量失败请求、重试和日志写入是否会把网关拖慢。
尤其要注意日志。成功请求日志通常稳定,异常请求如果把大量上下文都打出来,很可能在攻击、爬虫或下游故障时把 IO 打满。入口层越关键,越要把异常场景压出来,而不是只看正常流量下的漂亮曲线。
网关变更要有演练而不是口头保证
网关规则的风险不在代码行数,而在影响面。一个路由写错可能影响所有用户,一个限流阈值填错可能把正常流量挡掉,一个灰度条件漏了可能让新版本全量曝光。因此,网关变更最好像发布一样管理。
至少要有三件事:变更前能预览命中,变更中能观察关键指标,变更后能快速回滚。预览解决“会影响谁”;观察解决“有没有出问题”;回滚解决“出问题怎么办”。没有这三件事,网关配置就不应该频繁承接业务变化。
我会把网关的成熟度看成一个分水岭:如果团队只能靠人工改配置,那就少放动态业务逻辑;如果团队已经有审计、预览、灰度和回滚,再考虑承接更复杂的入口治理。能力没到位时,克制就是最好的架构选择。
一个可执行的拆分顺序
如果网关已经变得很重,别急着全部重构。先把现有规则按四类标记:安全入口、流量治理、业务语义、临时兼容。前两类大多可以留下,第三类评估迁移,第四类补下线日期。
接着挑影响最大但风险可控的一类先动。比如先清理临时兼容规则,或者把某个业务状态判断迁回服务层。每迁一个,都要补一条观测:迁走以后错误率、耗时和命中量有没有变化。否则迁移只是在文件之间搬代码。
网关的理想状态不是“什么都不做”,而是“只做自己能长期解释的事”。入口越稳定,下游服务越能专注业务,整个系统的变化成本才会降下来。