主题
界面
主题
Spring Cloud 与 Sentinel 是「SDK 模式」;服务网格把同一批治理能力搬进 Sidecar 代理,让应用零改动。
★ 本节用 JDK 自带的 HttpServer 手写一个「微型 Sidecar」,三组治理全部实测 ✓✓:
金丝雀分流:200 个请求 → v1=179(90%)| v2=21(11%)✓✓(业务服务不知道有灰度)
超时重试 :slow 实例超时 200ms → **代理自动重试到健康实例** → 客户端拿到结果 ✓✓
熔断 :连续 3 次失败 → 熔断打开 → 10 个请求里 **只有 3 次打到后端,7 次快速失败** ✓✓✓★ SDK 模式的四个痛点 ✗✗(本节实测的每一项,网格都换了个位置解决):
| 痛点 | 后果 |
|---|---|
| 侵入性:每个应用引依赖、写配置 | 业务代码与治理代码耦合 ✗ |
| 多语言:每种语言一套 SDK | Go/Python/前端服务享受不到治理 ✗✗ |
| 升级难:改规则要重新发版 | 治理规则变更跟着业务版本走 ✗ |
| 不一致:不同团队配置不同 | 同一个故障,线上表现千奇百怪 ✗✗ |
SDK 模式 :[业务逻辑 + 治理逻辑] ← 同一个进程(Spring Cloud/Sentinel)
网格模式 :[业务逻辑] ←(Sidecar 代理)← 治理逻辑下沉★ 一句话 ✓✓:服务网格 = 一组与应用同生命周期的轻量代理(数据面)+ 一套统一下发规则的控制面 ✓✓。
| 平面 | 组成 | 职责 | 类比 |
|---|---|---|---|
| 数据面 | 每个 Pod 一个 Sidecar(Envoy 等) | 实际转发流量:路由、超时、重试、mTLS | 每个路口的交警 |
| 控制面 | Istio 控制面 | 下发规则、证书、遥测配置 | 交管局(定规则) |
★★ 关键认知 ✓✓✓:治理能力本质上没变(《高并发系统设计》 的限流、《高可用系统设计》 的熔断、《Sentinel 限流与熔断》 的规则), 变的只是「谁执行」——从应用进程变成了它身边的代理 ✓✓。
发送 200 个请求:v1=179(90%)| v2=21(11%)✓✓
★ 业务服务只返回「我是 v1/v2」,**不知道有灰度这回事** ✓✓✓
★ 发布新版本 = 改代理的权重配置(或控制面下发规则),**应用零改动、零重启** ✓✓★ 对比 SDK 模式 ✓:同一件事要引入负载均衡组件 + 写配置 + 改代码 + 重新发版 ✗✓。
第 1 次尝试:slow 实例超时(>200ms)✗ → 代理重试到健康实例
客户端看到的结果:backend=fast ← 重试成功(业务代码完全没写重试)✓✓★★ 但请记住 《高可用系统设计》 的教训 ✓✓✓:网格里的重试同样要配预算与退避 —— 重试发生在代理层,不代表它不会引发重试风暴 ✗✗(Istio 默认就有重试预算相关的 retryBudget 配置)。
熔断器:连续 3 次失败 → **打开**(冷却 1 秒,期间不打后端)✗✓
10 个请求结束:真实打到后端 3 次,代理快速失败 7 次★ 三态回顾 ✓(《Sentinel 限流与熔断》):关闭 → 打开(快速失败)→ 半开(探测恢复); 实测里「3 次打到后端、7 次快速失败」正是「打开」期间的价值:保护后端不被无效流量淹没 ✓✓✓。
| 维度 | SDK 模式 | Sidecar(网格) |
|---|---|---|
| 侵入性 | 应用引依赖、写配置 ✗ | 应用零改动 ✓✓✓ |
| 多语言 | 每种语言一套 SDK ✗✗ | 与语言无关 ✓✓✓ |
| 治理规则升级 | 重新发版 ✗ | 控制面热更新 ✓✓ |
| 延迟开销 | 进程内,极低 ✓✓ | 多一跳代理(毫秒级)⚠️ |
| 资源开销 | 无额外进程 ✓ | 每 Pod 一个 Sidecar ⚠️ |
| 排障 | 直接看应用日志 ✓ | 要看两侧日志/网格面板 ⚠️ |
★★ 选型建议 ✓✓✓:中小团队 / 单一语言 → 先用 SDK 模式(简单、够用); 多语言、大规模、规则频繁变 → 再上网格 ✓; 网格不替代可观测与容量规划 —— 它只是把治理从「代码里」搬到「基础设施里」✓✓。
// 代理收到请求 → 按权重选后端 → 带超时转发 → 失败重试 → 返回
boolean pickV1 = random.nextInt(100) < 90;
String body = fetchWithTimeout("http://" + backend + "/", Duration.ofMillis(200));★ 注意 ✓:代理里没有一行业务代码,业务服务里没有一行治理代码 —— 这就是「关注点分离」的物理实现 ✓✓。
① 本地配置(本节实测) → 简单,但每实例各自为政
② 控制面统一下发(Istio CRD) → 规则版本化、可审计 ✓✓
③ 动态限流(Sentinel 控制台) → 规则热更新 ✓网格的默认配置:重试 3 次、无预算 ✗✗ → 照样重试风暴([S6-017](./S6-017))
正解:网格 + 正确的策略配置 + 压测验证 ✓✓代码:labs/java-deep/src/main/java/cn/kb/learn/deep/architecture/ServiceMeshLesson.java(JDK HttpServer 手写微型 Sidecar,无额外依赖)
实测输出(节选):
===== 1. 金丝雀发布:代理按 90/10 分流(业务代码零改动)=====
发送 200 个请求:v1=179(90%)| v2=21(11%)✓✓
===== 2. 超时 + 重试:慢实例被代理自动绕过 =====
第 1 次尝试:slow 实例超时(>200ms)✗ → 代理重试到健康实例
客户端看到的结果:backend=fast ← 重试成功(业务代码完全没写重试)✓✓
===== 3. 熔断:连续失败后代理「快速失败」,保护后端 =====
熔断器:连续 3 次失败 → **打开**(冷却 1 秒,期间不打后端)✗✓
10 个请求结束:真实打到后端 3 次,代理快速失败 7 次| # | 错误 | 说明 |
|---|---|---|
| 1 | 以为网格能自动解决重试风暴 ✗✗ | 默认重试策略可能更激进 ✓✓ |
| 2 | 网格化后不做端到端压测 ✗✗ | 多一跳代理的延迟与 CPU 开销要实测 ✓ |
| 3 | 小团队强上网格 ✗ | 控制面运维成本可能超过收益 ✓✓ |
| 4 | 应用里既写 SDK 又依赖网格 ✗ | 双重治理 = 规则打架、排障灾难 ✗✗ |
| 5 | 把网格当可观测平台 ✗ | 指标/追踪仍需专门的采集与看板 ✓ |
ServiceMeshLesson 三段实验 ✓✓✓;VirtualService/DestinationRule 示例,把本节的权重、超时、熔断映射成 YAML ✓✓✓。验收方式:能画出「业务服务 + Sidecar + 控制面」的架构,并把本节三项治理映射到具体配置项。
扩展任务:为你的团队写一份《SDK 还是网格》决策文档:现状(语言数、团队规模)、痛点、迁移成本、试点方案 ✓✓
《云原生》 云原生 —— 从「治理能力」转向「应用与平台的契约」。
暂无