第 17 章 —— 通信域与集合域的隔离
本章目标: 本章完成后,开发者能够分别配置通信域和集合域,并用同名 entry key 的反例证明两层身份没有混写。
学习目标
- 区分
clusterId、serviceId与 collection locator。 - 解释消息为何要同时校验集群、服务和集合身份。
- 证明不同 locator 下的同名 entry key 是不同状态。
- 避免把 Spring bean name 当成 wire identity。
前置条件
- 已完成第 3 章 locator 与第 10 章
serviceId。 - 已完成第 16 章 Spring bean 注册。
- 能区分 Java 容器标识与分布式协议标识。
案例进度
网关和 worker 都使用 entry key
fulfillment-primary。它们运行在同一履约 Runtime
中,却分别属于 route-hints 与
shard-owners。与此同时,另一个测试环境使用相同
locator,但不同 cluster/service 身份,也不能收到生产消息。
两层边界,不是一串可互换的名字
| 标识 | 作用范围 | 解决的问题 |
|---|---|---|
clusterId |
Runtime/sync envelope | 消息是否属于同一个部署集群 |
serviceId |
membership 与 sync envelope | 哪些服务实例能发现并交换 DSM 消息 |
tenantId |
collection locator | 状态归属的租户/命名空间 |
applicationId |
collection locator | 哪个应用子域拥有集合 |
collectionId |
collection locator | 具体集合的稳定身份 |
Spring bean-name |
单个应用上下文 | 代码如何选择一个已注册 handle |
entryKey |
单个集合内部 | 集合中的具体实体 |
entryKey 只有和完整 locator 放在一起才有意义。相同
entryKey 出现在不同 collectionId 或 applicationId
下,不会自动表示同一业务对象。
消息到达还要过两次身份检查
成员传输会拒绝不同 serviceId
的发现或消息;RuntimePlatformSyncService 还会校验 envelope
中的 clusterId 和
serviceId。通过通信域之后,collection route 再按 locator
找具体 handle。
因此,隔离不是只靠一个字段:
网络可达
→ clusterId/serviceId 匹配
→ 集合 descriptor/locator 匹配
→ schema/capability 匹配
→ entryKey 在目标集合内应用
每一层拒绝都应有可观察原因;不能把所有「看不到数据」都归因于 locator。
RuntimeIntegrationTest
的同名 key 反例
测试在一个 Runtime 中注册:
shared/gateway/route-hintsshared/worker/route-hints
两个 Register 都写入 same-key,一个值是
gateway-value,另一个是 worker-value。最终两边
size 都是 1,并各自读回自己的值。这直接证明 locator,而不是 Java entity
类型或 entry key,决定集合归属。
改名是协议迁移,不是代码重构
修改 bean alias 只影响当前 Spring 上下文;修改 locator、clusterId 或 serviceId 会改变分布式通信与状态身份。后者需要双写/迁移、兼容窗口或明确冷启动策略,不能作为普通 rename 直接上线。
反例与故障注入
- 两个集合配置相同 locator,Spring 启动应拒绝重复注册。
- 两个 Runtime 使用不同 serviceId,期望它们不形成同一成员视图。
- 同一 Runtime 用不同 applicationId 写同名 key,期望值互不覆盖。
- 只改 bean alias,确认 locator 与 wire identity 保持不变。
实验
cd submodule/dsm
mvn -q -pl dsm-integration-test,dsm-cluster -am \
-Dtest=RuntimeIntegrationTest,MulticastClusterMembershipTest \
-Dsurefire.failIfNoSpecifiedTests=false test再检查
isolation-cases.json:每个场景都应明确变化的是通信域、集合域还是应用上下文名。
实验验收卡
| 字段 | 内容 |
|---|---|
| 运行命令 | 上述 Runtime 与 membership 聚焦测试;书籍资产测试 |
| 输入或故障 | 同名 key、不同 locator、不同 serviceId、重复 locator |
| 可观察结果 | locator 隔离值;serviceId 隔离成员;重复 locator fail fast |
| 证据等级 | E2 单 Runtime 隔离 + E3 受控多节点 membership |
| 本实验未证明 | 操作系统/网络层强隔离、访问控制授权或租户数据合规 |
回顾
clusterId/serviceId控制通信域,locator 控制集合域。- bean name 只服务于依赖注入,不是 wire identity。
- 相同 entity 类型和 entry key 不会跨 locator 自动合并。
- 分布式身份改名需要迁移计划。
下一步
第 18 章把前四篇的测试整理成证据阶梯,明确每一层证明了什么、没有证明什么。