跳到主要内容
约 10 分钟5 张卡

服务网格

服务网格(Service Mesh)把服务间通信中的通用能力交给统一管理的数据面处理,例如路由、连接保护、身份验证和通信指标。控制面负责生成和分发策略,数据面在请求经过时执行这些策略。

它解决的是多个服务重复实现通信治理的问题。业务可以用不同语言编写,但仍需要一致的超时、访问策略和观测方式。把这些能力移到代理并不意味着业务不再关心网络:请求是否允许重试、用户能否访问某份数据,仍需要应用判断。下面以 Istio 的 sidecar 代理模式说明执行过程。

1. 面试核心​

先记住这几条,再读正文
  • 服务网格通过统一管理的数据面治理服务间通信。它不负责决定服务怎样拆分,也不是只有一个入口代理。卡 · 通信治理与业务逻辑
  • 控制面下发配置,数据面转发请求。已有流量能否跨越控制面断连,取决于本地配置、目标和证书是否仍有效。卡 · 数据面与控制面
  • 应用与代理的重试、超时需要协调。代理不知道一次业务副作用是否已经成功,重试可能放大流量或重复执行。卡 · 超时与重试的协调
  • mTLS 验证通信双方的工作负载身份并加密链路,不能自动代替用户级、资源级授权。卡 · 工作负载身份与访问策略
  • 代理可以生成通信指标和追踪片段,但应用仍需传播调用上下文,补充内部业务观测。卡 · 通信观测与应用上下文
  • 网格减少部分语言 SDK 的重复治理逻辑,同时增加代理资源、转发延迟、配置发布和排障成本,是否采用要由实际需求决定。

2. 通信治理与业务逻辑​

假设订单服务要调用库存服务。没有网格时,订单服务使用的客户端库可能负责地址发现、负载均衡、超时、重试和 TLS。随着服务使用不同语言,每种客户端库都需要实现、升级并正确配置这些能力。

网格把其中适合在通信层处理的能力放到代理。订单服务仍发出请求,但请求先经过本地代理;代理按统一下发的规则选择库存实例、建立连接并记录通信结果。治理规则的更新不必都依赖业务代码重新发布。

这与微服务架构解决的不是同一件事。微服务架构决定业务能力、部署和数据的边界;网格治理拆分之后的通信。把过细的服务拆分接入网格,不会自动减少跨服务调用,也不会修复不合理的数据依赖。

方式通信能力在哪里执行主要需要权衡什么
应用 SDK业务进程内的客户端库容易结合业务语义,但需要管理多语言、多版本和应用升级
服务网格统一管理的数据面,典型实现使用独立代理可统一部分通信策略,但增加代理、流量接入与配置治理成本
API 网关对外或跨边界的入口代理集中管理入口,不自动覆盖每一条服务间调用

这些方式可以共存。比如外部请求先经过 API 网关,内部调用再进入网格;应用 SDK 仍处理序列化、业务超时预算、上下文传播和错误结果。

3. 数据面与控制面​

Sidecar 是与应用共同部署、协助应用工作的独立组件。在 Istio 的 sidecar 模式中,Envoy 代理通常与应用一起运行,负责纳入网格的入站和出站流量。它在请求路径上,属于数据面。

以“订单服务调用库存服务”为例,启用了相应流量接管与 mTLS 策略后,一次调用可以按下面的路径执行:

  1. 订单服务发起请求,出站流量被导向订单侧代理。
  2. 订单侧代理根据本地路由与实例信息,选择库存实例。
  3. 两侧代理按配置建立 mTLS 连接,验证对端工作负载身份。
  4. 库存侧代理执行适用的访问策略,再把请求交给库存应用。
  5. 响应沿调用链返回,代理记录状态、耗时等通信信息。

控制面不需要夹在每个业务请求中转发请求体。Istio 的 istiod 提供服务发现、配置和证书管理,把高层规则转换为代理需要的配置。代理使用已经取得的本地状态转发,而不是每来一个请求就向控制面查询一次路由。

这不表示数据面永远没有同步依赖。如果配置了远程授权服务或集中式配额检查,相应请求仍可能依赖那个外部服务。要区分“获取配置的控制面”与“请求处理时调用的外部决策服务”。

Sidecar 也不是服务网格的唯一部署方式。Istio 的 ambient 模式把部分能力放到节点级代理,并按需通过其他代理提供应用层能力。理解网格时要看谁接管流量、谁执行策略和故障影响到哪里,不能把“每个应用旁边放一个代理”当作所有实现的定义。

4. 流量策略与重试边界​

网格能在代理处统一执行可识别协议的流量规则。例如,按请求属性选择目标版本、在多个实例间负载均衡、限制连接与排队资源、设置超时和有限重试。这些规则以实际进入代理的流量为前提,绕过代理的路径不会自动获得同样保护。

能力还取决于代理能看到哪一层协议。只按 TCP 连接转发时,不能假装已经理解 HTTP 路径;应用自己建立的端到端 TLS 若没有在代理处终止,代理也不能直接读取其中的 HTTP 请求头,再按这些头做应用层路由。

4.1 超时与重试的协调​

一次业务调用需要整体时间预算,而不只是每一层都有一个超时参数。若应用在 1 秒时就放弃,代理还按 3 秒预算继续尝试,额外工作可能已经无法给原调用者带来成功结果。具体的预算传播和取消见超时。

多层重试还会相乘。假设应用最多发起 3 次尝试,每次进入代理后,代理又最多向下游尝试 3 次;在每层都用完额度的情况下,原来的一次业务调用最多触发 3 × 3 = 9 次下游尝试。这里的 3 都包含首次调用,不是“首次加上 3 次重试”。

库存扣减已经成功但响应丢失时,代理看到的可能只是超时,无法据此认定可以安全地再扣一次。重试条件、总次数、退避和业务幂等需要一起设计,见重试。网格可以执行策略,不能替应用决定业务是否允许重复。

4.2 保护策略与业务恢复​

连接池上限、排队限制和异常实例摘除可以减少故障扩散,但它们不能创造下游容量。库存所有实例都不可用时,代理只能按策略失败或拒绝,应用仍需决定返回“稍后重试”、读取允许的缓存,还是撤销已经开始的业务流程。

发布策略也要核对实际生效范围。控制面接受了配置,不意味着每个代理同时应用完成;流量切换需要观察目标版本、代理配置和实际请求结果,具体见灰度发布。

5. 工作负载身份与访问策略​

mTLS(双向 TLS)让连接双方都提供身份凭据并验证对方,同时保护链路上的数据。在网格中,证书通常关联工作负载身份,策略据此决定“订单服务是否可以调用库存服务”。证书和密钥的分发、轮换,也由网格相关组件协调。

这不等于“用户张三是否可以修改订单 123”。前者验证服务身份,后者还需要用户身份、资源归属和业务权限。网格可以提供部分请求认证与访问策略,但应用的资源级判断不能因为链路已加密就取消,见认证与授权。

是否强制加密也要看策略。以 Istio 的对等认证模式为例,PERMISSIVE 可以同时接受明文与 mTLS,适合迁移过程;STRICT 要求受该策略保护的连接使用 mTLS。仅仅部署了代理,不能据此宣布所有路径都已禁止明文。

保护范围应沿实际链路确认。在上面的 sidecar 调用中,代理之间可以使用 mTLS,应用与本地代理之间则可能是本地明文连接。外部客户端到入口网关、网关到内部服务,也可能是不同的 TLS 区段。密码学与端点边界见密码学基础和 TLS。

6. 通信观测与应用上下文​

代理能观察经过自己的请求和响应,生成请求量、错误、延迟、连接等指标,也能记录访问日志和追踪片段。它因此提供了一套跨语言的通信视角,但看不到应用内部所有原因。

例如,订单服务返回很慢,代理可以测到这次调用耗时,却不能仅凭网络流量区分它是在等待数据库、持有互斥锁,还是执行了一段耗时计算。这些信息仍需应用日志、内部指标或追踪埋点补充。

追踪上下文把不同服务里的调用片段关联到同一次请求。订单服务收到一个请求,再发起库存查询时,需要把对应上下文传给出站请求。代理虽然看到了入站和出站流量,却不能自动推断“这十个并发入站请求中,究竟哪一个触发了这次库存查询”。

所以,网格生成了追踪片段,不代表完整链路就一定连好了。应用仍应通过客户端库或追踪 SDK 正确传播上下文,并核对采样和后端接收情况,具体见可观测性。

7. 故障影响与使用代价​

控制面和数据面的故障影响不同。控制面短暂断连时,已经运行的代理可能继续使用有效配置;但配置无法更新,新实例可能拿不到启动所需的路由和凭据。控制面恢复后,还要核对各代理的状态是否收敛。

故障或变化需要判断的具体影响
控制面暂时不可达现有代理是否有可用配置,新实例是否能就绪
实例地址变化但配置未更新旧路由是否仍指向健康、正确的目标
证书无法续期到期后新的 TLS 握手能否通过;不能只看现有长连接还在运行
代理崩溃或资源耗尽该代理承接的流量是否中断,是否存在绕过策略的意外路径
错误策略成功分发可能同时影响多个服务,控制面健康并不能阻止逻辑配置错误
遥测量激增代理、网络和观测后端是否因额外负载受影响

“本地有配置”不意味着它可以无限期使用,地址、身份和权限都会变化。更细的失联与恢复条件见控制平面与数据平面。

代理还会占用 CPU、内存、连接和队列,并让请求多经过一些处理步骤。延迟取决于协议、过滤器、TLS、遥测、负载和部署方式,不能用一个固定毫秒数代表所有网格。评估时应比较目标负载下的吞吐、错误率和尾延迟,还要计算配置发布、升级和排障的投入。

多语言服务较多、通信策略需要统一、工作负载身份管理复杂时,网格的收益可能更明显。若服务数量少、已有客户端库能够满足需求,新增网格未必能抵消运行成本。选择依据应是具体治理缺口,而不是“用了微服务就必须上网格”。

8 · 面试题卡片​

本页题目与参考回答

8.1 什么是服务网格?​

考察重点:服务间通信治理、控制面与数据面、代理与应用的职责。

相关内容:通信治理与业务逻辑、数据面与控制面。

参考回答

**服务网格通过统一管理的数据面,为服务间通信提供路由、身份验证、流量保护和观测等能力。**控制面生成并分发配置,数据面在请求经过时执行这些规则。

以 sidecar 模式为例,应用的调用经过两侧代理,代理按配置选实例、建立安全连接并记录通信结果。这样能减少多语言客户端重复实现通用治理逻辑,但仍要承担代理和配置管理成本,应用也继续负责业务权限、幂等和上下文传播。

8.2 服务网格控制面故障,为什么不能简单判断为“全部中断”或“完全没影响”?​

考察重点:本地配置、实例变化、证书生命周期与启动依赖。

相关内容:数据面与控制面、故障影响与使用代价。

参考回答

**已有代理可以在配置、目标和凭据仍有效时继续转发,但失联会阻断更新,并影响需要新配置或证书的操作。**新实例可能无法就绪,旧地址可能失效,证书到期后新的握手也可能失败。

还要单独判断代理是否健康,以及是否存在远程授权等同步依赖。控制面与数据面分离减少了一类故障耦合,没有消除所有依赖。

8.3 应用和代理都重试,为什么可能让故障更严重?​

考察重点:多层尝试次数、整体时间预算、结果未知与幂等。

相关内容:超时与重试的协调。

参考回答

**多层重试可能相乘,并在下游已经过载时继续放大请求。**应用每次业务调用最多尝试 3 次,代理对每次应用请求又最多尝试 3 次,额度全部用完时就可能产生 9 次下游尝试。

还要协调总体截止时间和每次尝试预算。响应丢失不代表操作没有执行,代理不能自动判断扣款、扣库存是否可重试,应用需要提供相应的幂等与恢复机制。

8.4 服务间开启 mTLS 后,可以取消应用授权吗?​

考察重点:工作负载身份、终端用户身份、资源级权限与链路范围。

相关内容:工作负载身份与访问策略。

参考回答

**不能,mTLS 证明连接对端的身份并保护通信,不自动判断用户是否有权操作具体资源。**订单服务被允许调用库存服务,不代表每个用户都可以修改任意订单。

应继续检查用户凭据、资源归属和业务权限,也要确认哪些链路强制 mTLS。允许明文的迁移模式、未接入网格的路径和应用到本地代理的区段,不能被笼统视为同一条加密链路。

8.5 代理已经生成追踪片段,为什么完整调用链仍可能断开?​

考察重点:请求因果关系、上下文传播与通信观测的边界。

相关内容:通信观测与应用上下文。

参考回答

**应用还需要把入站请求的追踪上下文关联并传播到它触发的出站请求。**代理看得到两边的网络流量,却不能自动判断应用内部的调用因果关系。

上下文没有正确传递时,各代理可以产生独立片段,但这些片段无法拼成同一条链。还需核对采样和遥测后端,并用应用埋点解释数据库等待等内部耗时。

9. 参考资料​

来源:Coding 101 原文 · 免费阅读,引用请保留出处。内容使用说明