微服务治理:服务网格与网关选型对比
订单中心拆到第 11 个服务的那天,链路开始变得难查。一次下单要跨订单、库存、优惠、支付、风控五个服务,任何一跳超时都会让用户看到转圈。治理需求就这么冒出来了:限流、熔断、灰度、链路追踪、mTLS,一个都不能少。
摆在前面的方案有两条路。一条是把这些能力塞进网关,所有流量先过网关再进服务;另一条是上服务网格,让每个服务旁边挂一个 Sidecar,治理逻辑下沉到数据面。
先看网关派的做法
网关派的思路很直白:入口收敛,规则集中。业务代码零侵入,运维只维护一层。
# Spring Cloud Gateway 片段
routes:
- id: order-service
uri: lb://order-center
predicates:
- Path=/api/order/**
filters:
- name: CircuitBreaker
args:
name: orderCb
fallbackUri: forward:/fallback/order
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 500
redis-rate-limiter.burstCapacity: 1000
这段配置解决的是入口限流和熔断。关键点在 replenishRate 和 burstCapacity 的配比:前者是稳态 QPS,后者是瞬时突发上限,配成 1:2 比较稳,配成 1:10 会让下游在突发时直接被打穿。容易踩的坑是 fallbackUri 指向的降级接口本身又调了下游服务,熔断触发时反而制造二次雪崩。
网关派的代价也很清楚。它只管南北向流量,服务之间的东西向调用它看不见。订单调库存超时了,网关毫不知情,熔断规则形同虚设。想覆盖东西向,就得让服务互相调用也绕一圈网关,延迟直接翻倍,拓扑也乱成一团。
网格派怎么补这个洞
服务网格把治理能力从网关挪到每个 Pod 旁边的 Sidecar。服务 A 调服务 B,流量实际走 A 的 Sidecar → B 的 Sidecar,中间的熔断、重试、mTLS 全在 Sidecar 里做,业务代码无感。
┌─────────────┐ ┌─────────────┐
│ Order Pod │ │ Stock Pod │
│ ┌─────────┐ │ │ ┌─────────┐ │
│ │ Business│ │ │ │ Business│ │
│ └────┬────┘ │ │ └────┬────┘ │
│ ┌────▼────┐ │ mTLS │ ┌────▼────┐ │
│ │ Sidecar ├─┼─────────┼─► Sidecar │ │
│ └─────────┘ │ │ └─────────┘ │
└─────────────┘ └─────────────┘
▲ ▲
└────── Control Plane ───┘
(Istio / xDS)
控制面下发规则,数据面执行。这套结构的好处是东西向治理终于有了落点,A/B 测试、金丝雀发布、故障注入都能按服务粒度做。
代价是资源开销和延迟。每个 Sidecar 常驻约 50MB 内存、0.1 核 CPU,100 个 Pod 就是 5GB 内存的额外成本。每次跨服务调用多两跳本地代理,实测 P99 增加 1~3ms。对延迟敏感的交易链路,这个数字要提前算进预算。
选型不是二选一
真实项目里,两者不是替代关系。网关守边界,网格管内部,各管一段。判断标准可以落到三个问题:
服务数量。低于 20 个服务,网关 + SDK 熔断足够,上网格是杀鸡用牛刀。超过 50 个服务、多语言栈混用,网格的收益才盖过运维复杂度。
团队规模。网格要求有人懂 xDS、Envoy 配置、控制面升级。没有专职平台团队,网格会变成没人敢动的黑盒。
合规要求。金融、医疗场景要服务间 mTLS 和细粒度流量审计,网格几乎是唯一省力的解法。纯内部系统可以缓一缓。
一个折中路线是先网关后网格:第一年用网关 + Sentinel 覆盖入口和关键链路,把服务边界理清楚;第二年服务数过 50 再引入网格,优先给支付、风控这类合规敏感的服务挂 Sidecar,其余服务继续走 SDK。
下一步
选型这事没有银弹,只有匹配当前阶段的方案。如果你手上服务不到 30 个、团队没专职平台岗,先把网关的限流熔断配扎实,比追网格的热度实在得多。等东西向调用真的成为排查瓶颈那天,再谈网格也不迟。
本文关键词:微服务、服务网格、API 网关、熔断限流、Sidecar