简介

为了管理分布式系统中的通信复杂度(比如多个服务间调用、安全验证、数据监控等难题),技术团队通常会选择两种经典方案:

  • API 网关(API gateway)
  • 服务网格(service mesh) 这两种方案的共同目标是:让服务之间的通信更易管理(比如统一控制调用规则)、更安全(比如加密传输、身份验证)、更可观测(比如追踪调用链路、监控错误率)。

尽管目标一致,但二者的实现方式、适用场景完全不同。而 confusion(混淆)往往源于两种错误认知:

认为二者 “可互换”(interchangeable)—— 即觉得用哪种都一样,能互相替代; 把二者的作用简化成 “单纯的流量导向”,并流传出一个常见的 “简化说法”:

“API 网关负责南北向流量(north-south traffic),服务网格负责东西向流量(east-west traffic)” 这里的 “南北向 / 东西向” 是行业比喻:

  • 南北向流量:指系统 “外部客户端”(比如用户手机 APP、第三方系统)与 “系统内部服务” 之间的通信(类似 “从外界进入系统内部”,如用户 APP 调用后端支付服务);
  • 东西向流量:指系统 “内部不同服务” 之间的通信(类似 “系统内部横向调用”,如支付服务调用订单服务、订单服务调用库存服务)。

API 网关

简介

API 网关是提供给应用程序客户端的单点入口,通常位于客户端和一系列后端服务中间。

所有来自外部系统的请求(比如用户手机 APP、第三方平台调用、前端网页的请求等 “外界流量”),在到达系统内部的后端服务(比如支付服务、用户服务、订单服务等)之前,都必须先经过 API 网关这个 “集中化的中间层”。

痛点

API 网关模式的本质,是解决分布式系统的一个关键难题 —— 如何把 “分散的多个后端服务”,通过一个统一、可管理的入口对外提供服务。

运行位置

API 网关运行在 OSI 模型的第 7 层,也就是 “应用层”。这一层直接处理应用层协议(比如我们最常用的 HTTP/HTTPS 协议),而不是底层的 “传输层”(如 TCP 协议,只负责数据传输,不理解请求内容)或 “网络层”(如 IP 协议,只负责路由)。

因为工作在应用层,API 网关能 “看懂” 请求的完整内容,包括:

  • HTTP 请求本身:比如是 GET(查询)、POST(提交)还是 DELETE(删除)请求;
  • 请求头(headers):比如用户的身份令牌(token)、请求来源、数据格式(Content-Type)等;
  • 请求体(payloads):比如用户提交的表单数据、JSON 格式的业务参数(如订单金额、用户 ID)。

正因为能 “看懂” 请求内容,API 网关才能对请求进行精细化控制,比如:

  • 鉴权:检查请求头里的 token 是否有效,无效则直接拒绝,不让请求到达内部服务;
  • 路由:根据请求路径(如/api/user转发到用户服务,/api/order转发到订单服务);
  • 限流:如果某个用户短时间内发了 1000 次请求,网关可以拦截超出限制的请求,防止内部服务被压垮;
  • 数据转换:比如外部发的是 JSON 格式请求,内部服务需要 XML 格式,网关可以自动转换。

举个例子:如果外部发一个POST /pay的请求,网关能看到 “这是支付请求”“请求头里有用户 token”“请求体里有支付金额 100 元”—— 而如果是工作在底层的工具(如负载均衡器),只能看到 “这是一个 TCP 连接”,看不懂这些业务层面的内容。

API 网关会提供一系列功能:

  • 身份认证+安全策略
  • 负载均衡
  • 熔断保护
  • 协议转换
  • 服务发现
  • 监控
  • 日志
  • 计费
  • 缓存

服务网格 (Service Mesh)

简介

服务网格是分布式系统中的基础设施层(注意:不是业务层,不处理具体业务逻辑,只负责 “通信管理”),专门用来管理 “服务与服务之间的通信”(比如订单服务调用库存服务、支付服务调用用户服务的过程)。

和 API 网关的区别

API 网关聚焦 “外部边缘流量”(比如用户 APP、第三方系统对内部服务的请求),而服务网格聚焦 “内部流量”—— 即数据中心或云环境内,不同内部服务之间的调用流量(对应之前提到的 “东西向流量”)。

简单说:API 网关管 “门口的人进来”,服务网格管 “院子里的人互相走动”。

和传统 RPC 模式的区别

(1)传统模式的问题:“通信逻辑嵌入业务代码”(baking networking logic into application code)

在没有服务网格的分布式系统中,服务间通信的逻辑(比如 “如何重试失败的调用”“如何加密传输数据”“如何监控调用链路”)需要写在每个服务的业务代码里。

弊端:每个服务都要重复开发相同的通信逻辑,不仅冗余、易出错,还会让业务代码变得臃肿(“业务代码里混着大量非业务的网络代码”);如果要修改通信规则(比如换一种加密方式),所有服务都要重新开发、部署 —— 维护成本极高。

(2)服务网格的解决方案:“Sidecar 代理接管通信逻辑”

服务网格不把通信逻辑嵌入业务代码,而是把它 “委托”(delegates)给一种叫Sidecar 代理(sidecar proxies)的轻量级网络组件: Sidecar 的字面意思是 “边车”(比如摩托车旁边的小拖车),在这里指:每个服务实例启动时,都会 “附带启动一个 Sidecar 代理实例”,二者像 “主服务 + 边车” 一样绑定在一起(运行在同一台机器 / 容器中)。

举例:如果系统有 “订单服务” 的 3 个实例,那么会同时运行 3 个 Sidecar 代理实例,每个订单服务实例都对应一个专属的 Sidecar。

(3)Sidecar 代理的工作方式:“透明拦截、无感执行” “These proxies intercept all inbound and outbound traffic, enforcing policies without requiring services to be aware of them.”

第一步:“全流量拦截”(intercept all inbound and outbound traffic)服务的所有 “入站流量”(其他服务调用它的请求)和 “出站流量”(它调用其他服务的请求),都会被自己的 Sidecar 代理 “拦截”—— 也就是说,服务不再直接与其他服务通信,而是所有通信都要经过 Sidecar 中转。比如:订单服务要调用库存服务时,请求会先发给订单服务的 Sidecar,再由这个 Sidecar 转发给库存服务的 Sidecar,最后由库存服务的 Sidecar 把请求交给库存服务;响应则按相反路径返回。

第二步:“无感执行策略”(enforcing policies without services’ awareness)Sidecar 代理会按照服务网格的统一规则(比如 “所有通信必须用 TLS 加密”“调用失败时自动重试 3 次”“记录调用日志”),在拦截流量的过程中 “悄悄执行” 这些规则 —— 而业务服务本身完全不需要知道 Sidecar 的存在,也不需要修改任何代码。这就实现了 “通信逻辑与业务逻辑的彻底解耦”:要修改通信规则时,只需更新服务网格的统一配置(Sidecar 会自动获取新规则),所有服务都不用动 —— 极大降低了维护成本。

核心价值

将 “网络通信逻辑”(比如路由、加密、重试等)从应用业务代码中 “转移”(shifts)到了基础设施层(即服务网格本身)。

带来的 3 大关键价值:

  • 一致性(consistency):所有服务的通信规则(如加密标准、重试策略)由服务网格统一管控,不会出现 “A 服务用 TLS 加密,B 服务明文传输” 的混乱情况;
  • 安全性(security):通信安全逻辑(如身份验证、数据加密)由基础设施层强制执行,无需依赖每个服务自己实现(避免因业务团队疏忽导致的安全漏洞);
  • 可观测性(observability):服务间通信的日志、链路追踪、监控数据由服务网格统一收集,无需在每个服务中埋点开发;

关键前提:这一切都无需 “触碰”(touch)业务服务的逻辑 —— 服务只需专注于 “处理订单”“查询用户” 等核心业务,完全不用关心通信细节

组成部分

服务网格通过 “数据平面 + 控制平面” 的分离架构,实现了 “分布式执行” 与 “集中化管理” 的平衡。二者分工明确,共同完成服务通信的管理。

数据平面(Data Plane)

组成:由Sidecar 代理构成(即之前提到的 “与每个服务实例绑定的轻量级代理”),每个服务实例都对应一个专属的 Sidecar,是 “一对一” 的配对关系。

核心角色:“流量处理的直接执行者”,直接位于请求的执行路径上(所有服务间的通信都必须经过 Sidecar 中转),具体做 4 类关键工作:

  • 流量路由:根据规则把请求转发到正确的服务实例(比如 “把订单查询请求转发到订单服务的 3 号实例”);
  • 加密与认证:对服务间的通信数据进行 TLS 加密,同时验证通信双方的身份(确保是 “自己人” 在通信,防止伪装攻击);
  • 故障恢复:请求失败时自动重试、超时控制(比如 “调用库存服务失败后,重试 2 次再返回错误”);
  • 其他:还包括限流(防止某个服务被过度调用)、流量镜像(把生产流量复制一份到测试服务,用于验证新功能)等。

部署特点:去中心化(decentralized)——Sidecar 代理跟随服务实例分布在整个系统中(服务部署在哪个节点,Sidecar 就跑在哪个节点),没有 “单点故障” 风险(某一个 Sidecar 挂了,只影响对应的一个服务实例,不影响全局)。

控制平面

服务网格的 “大脑”(brain of the operation),不直接处理流量,而是负责制定规则、下发配置,具体做 3 类关键工作:

  • 下发配置与策略:把统一的通信规则(如路由策略、加密标准、限流阈值)推送给所有 Sidecar 代理(比如 “通知所有 Sidecar,从今天起通信必须用 TLS 1.3 加密”);
  • 管理服务身份:为每个服务实例分配唯一的 “身份标识”(类似 “身份证”),用于 Sidecar 之间的身份验证(确保只有授权服务能通信);
  • 协调更新:统一管理 Sidecar 的配置更新(比如滚动更新规则,避免所有 Sidecar 同时重启导致的流量中断)。

不在请求路径上(not on the request path)—— 这意味着控制平面的性能波动(如短暂延迟)不会影响实际业务流量的传输,能有效降低整体系统的 latency(延迟);但同时要求所有 Sidecar 必须与控制平面保持 “连接与同步”(connected and in sync),否则 Sidecar 会失去最新的配置,导致通信规则失效。

价值

分离架构的价值:

  • 数据平面专注于 “处理流量”,只做必要的轻量级操作(如转发、加密),保证通信速度快、延迟低;
  • 控制平面专注于 “管理规则”,所有配置和策略都在一个地方集中操作(比如运维人员只需在控制平面修改一次限流规则,所有 Sidecar 都会自动生效),大幅降低管理复杂度。