Skip to content

服务网格 ​

S6-019选修高级约 60 分钟JDK 21Java 高级与架构 · 架构设计

1. 本节定位 ​

Spring Cloud 与 Sentinel 是「SDK 模式」;服务网格把同一批治理能力搬进 Sidecar 代理,让应用零改动。

★ 本节用 JDK 自带的 HttpServer 手写一个「微型 Sidecar」,三组治理全部实测 ✓✓:

text
金丝雀分流:200 个请求 → v1=179(90%)| v2=21(11%)✓✓(业务服务不知道有灰度)
超时重试 :slow 实例超时 200ms → **代理自动重试到健康实例** → 客户端拿到结果 ✓✓
熔断    :连续 3 次失败 → 熔断打开 → 10 个请求里 **只有 3 次打到后端,7 次快速失败** ✓✓✓

2. 学习目标 ​

  • 说清 SDK 模式的四个痛点与服务网格的答案 ★★★;
  • 知道数据面(Sidecar)与控制面的分工 ★★★;
  • 能解释金丝雀、超时重试、熔断在代理层如何实现 ★★★;
  • 能为团队选择「SDK 还是网格」并说出依据 ★★★。

3. 前置知识检查 ​

4. 为什么需要这个知识 ​

★ SDK 模式的四个痛点 ✗✗(本节实测的每一项,网格都换了个位置解决):

痛点后果
侵入性:每个应用引依赖、写配置业务代码与治理代码耦合 ✗
多语言:每种语言一套 SDKGo/Python/前端服务享受不到治理 ✗✗
升级难:改规则要重新发版治理规则变更跟着业务版本走 ✗
不一致:不同团队配置不同同一个故障,线上表现千奇百怪 ✗✗

5. 核心概念 ​

5.1 服务网格的位置:把治理从「代码」搬到「基础设施」★★★ ​

text
SDK 模式 :[业务逻辑 + 治理逻辑] ← 同一个进程(Spring Cloud/Sentinel)
网格模式 :[业务逻辑] ←(Sidecar 代理)← 治理逻辑下沉

★ 一句话 ✓✓:服务网格 = 一组与应用同生命周期的轻量代理(数据面)+ 一套统一下发规则的控制面 ✓✓。

5.2 数据面与控制面 ★★ ​

平面组成职责类比
数据面每个 Pod 一个 Sidecar(Envoy 等)实际转发流量:路由、超时、重试、mTLS每个路口的交警
控制面Istio 控制面下发规则、证书、遥测配置交管局(定规则)

★★ 关键认知 ✓✓✓:治理能力本质上没变(《高并发系统设计》 的限流、《高可用系统设计》 的熔断、《Sentinel 限流与熔断》 的规则), 变的只是「谁执行」——从应用进程变成了它身边的代理 ✓✓。

5.3 金丝雀分流:改权重即可,应用零改动(实测)★★★ ​

text
发送 200 个请求:v1=179(90%)| v2=21(11%)✓✓
★ 业务服务只返回「我是 v1/v2」,**不知道有灰度这回事** ✓✓✓
★ 发布新版本 = 改代理的权重配置(或控制面下发规则),**应用零改动、零重启** ✓✓

★ 对比 SDK 模式 ✓:同一件事要引入负载均衡组件 + 写配置 + 改代码 + 重新发版 ✗✓。

5.4 超时与重试:慢实例被自动绕过(实测)★★★ ​

text
第 1 次尝试:slow 实例超时(>200ms)✗ → 代理重试到健康实例
客户端看到的结果:backend=fast ← 重试成功(业务代码完全没写重试)✓✓

★★ 但请记住 《高可用系统设计》 的教训 ✓✓✓:网格里的重试同样要配预算与退避 —— 重试发生在代理层,不代表它不会引发重试风暴 ✗✗(Istio 默认就有重试预算相关的 retryBudget 配置)。

5.5 熔断:后端挂了就别再「考验」它(实测)★★★ ​

text
熔断器:连续 3 次失败 → **打开**(冷却 1 秒,期间不打后端)✗✓
10 个请求结束:真实打到后端 3 次,代理快速失败 7 次

★ 三态回顾 ✓(《Sentinel 限流与熔断》):关闭 → 打开(快速失败)→ 半开(探测恢复); 实测里「3 次打到后端、7 次快速失败」正是「打开」期间的价值:保护后端不被无效流量淹没 ✓✓✓。

5.6 SDK 模式 vs Sidecar 模式(实测对照)★★★ ​

维度SDK 模式Sidecar(网格)
侵入性应用引依赖、写配置 ✗应用零改动 ✓✓✓
多语言每种语言一套 SDK ✗✗与语言无关 ✓✓✓
治理规则升级重新发版 ✗控制面热更新 ✓✓
延迟开销进程内,极低 ✓✓多一跳代理(毫秒级)⚠️
资源开销无额外进程 ✓每 Pod 一个 Sidecar ⚠️
排障直接看应用日志 ✓要看两侧日志/网格面板 ⚠️

★★ 选型建议 ✓✓✓:中小团队 / 单一语言 → 先用 SDK 模式(简单、够用); 多语言、大规模、规则频繁变 → 再上网格 ✓; 网格不替代可观测与容量规划 —— 它只是把治理从「代码里」搬到「基础设施里」✓✓。

6. 递进示例 ​

6.1 一个 Sidecar 代理的最小骨架 ​

java
// 代理收到请求 → 按权重选后端 → 带超时转发 → 失败重试 → 返回
boolean pickV1 = random.nextInt(100) < 90;
String body = fetchWithTimeout("http://" + backend + "/", Duration.ofMillis(200));

★ 注意 ✓:代理里没有一行业务代码,业务服务里没有一行治理代码 —— 这就是「关注点分离」的物理实现 ✓✓。

6.2 治理规则的三种下发方式 ​

text
① 本地配置(本节实测)        → 简单,但每实例各自为政
② 控制面统一下发(Istio CRD) → 规则版本化、可审计 ✓✓
③ 动态限流(Sentinel 控制台) → 规则热更新 ✓

6.3 反例:以为「上了网格就自动高可用」 ​

text
网格的默认配置:重试 3 次、无预算 ✗✗ → 照样重试风暴([S6-017](./S6-017))
正解:网格 + 正确的策略配置 + 压测验证 ✓✓

7. 完整可运行代码与实测 ​

代码:labs/java-deep/src/main/java/cn/kb/learn/deep/architecture/ServiceMeshLesson.java(JDK HttpServer 手写微型 Sidecar,无额外依赖)

实测输出(节选):

text
===== 1. 金丝雀发布:代理按 90/10 分流(业务代码零改动)=====
  发送 200 个请求:v1=179(90%)| v2=21(11%)✓✓

===== 2. 超时 + 重试:慢实例被代理自动绕过 =====
  第 1 次尝试:slow 实例超时(>200ms)✗ → 代理重试到健康实例
  客户端看到的结果:backend=fast ← 重试成功(业务代码完全没写重试)✓✓

===== 3. 熔断:连续失败后代理「快速失败」,保护后端 =====
  熔断器:连续 3 次失败 → **打开**(冷却 1 秒,期间不打后端)✗✓
  10 个请求结束:真实打到后端 3 次,代理快速失败 7 次

8. Debug 观察点 ​

  1. 把金丝雀权重从 90/10 改成 50/50:观察分流比例 ✓✓;
  2. 把代理超时从 200ms 调到 600ms:观察「超时不再发生,但客户端变慢」的取舍 ⚠️✓;
  3. 把熔断阈值从 3 次改成 10 次:观察熔断更晚触发、后端承受更多失败流量 ✗✓;
  4. 给代理加「重试预算」:复现 《高可用系统设计》 的收敛效果 ✓✓✓。

9. 常见错误 ​

#错误说明
1以为网格能自动解决重试风暴 ✗✗默认重试策略可能更激进 ✓✓
2网格化后不做端到端压测 ✗✗多一跳代理的延迟与 CPU 开销要实测 ✓
3小团队强上网格 ✗控制面运维成本可能超过收益 ✓✓
4应用里既写 SDK 又依赖网格 ✗双重治理 = 规则打架、排障灾难 ✗✗
5把网格当可观测平台 ✗指标/追踪仍需专门的采集与看板 ✓

10. 动手实验 ​

  1. 跑 ServiceMeshLesson 三段实验 ✓✓✓;
  2. 给代理加一个「镜像流量」能力:把 10% 请求复制发到 v2(不影响响应)✓✓;
  3. 用真实服务复现:写一个 Spring Boot 服务 + Nginx/Envoy 前置代理,对比「SDK 熔断 vs 代理熔断」✓✓;
  4. 阅读 Istio 的 VirtualService/DestinationRule 示例,把本节的权重、超时、熔断映射成 YAML ✓✓✓。

验收方式:能画出「业务服务 + Sidecar + 控制面」的架构,并把本节三项治理映射到具体配置项。

扩展任务:为你的团队写一份《SDK 还是网格》决策文档:现状(语言数、团队规模)、痛点、迁移成本、试点方案 ✓✓

11. 练习题 ​

  1. SDK 模式的四个痛点是什么?网格分别怎么解决?
  2. 数据面与控制面的分工?
  3. 金丝雀分流为什么能做到「应用零改动」?
  4. 网格里的重试为什么仍然可能引发雪崩?
  5. 什么情况下不建议上服务网格?
参考答案(要点)
  1. 侵入/多语言/升级难/不一致;下沉到 Sidecar + 控制面统一 ✓✓★
  2. 数据面转发流量执行策略;控制面下发规则与证书 ✓✓★
  3. 路由是代理的职责,改权重不碰应用代码与镜像 ✓✓★
  4. 重试发生在哪一层都要放大流量,必须配预算与退避 ✓✓★
  5. 小团队 / 单一语言 / 治理需求简单(SDK 足够);运维能力不足时 ✗✓★

12. 掌握标准 ​

  • [ ] 能说清 SDK 与网格的取舍 ★★★;
  • [ ] 知道数据面/控制面分工 ★★★;
  • [ ] 能把金丝雀/超时/熔断映射到代理配置 ★★★;
  • [ ] 知道网格不改变「治理的物理规律」★★★;
  • [ ] 能给团队做出选型判断 ★★★。

13. 扩展资源 ​

14. 下一步学习 ​

《云原生》 云原生 —— 从「治理能力」转向「应用与平台的契约」。

后续知识

暂无

进度只保存在本机浏览器,可随时清除

个人学习项目:AI 生成内容均经人工复核,第三方资源仅作索引