2. DDS基础概念
DDS(Data Distribution Service,数据分发服务)是一套面向实时分布式系统的数据通信中间件标准。它最核心的思想不是“把消息发给某个地址”,而是“让需要数据的人自动拿到数据”。理解 DDS,必须从发布订阅模型、以数据为中心、全局数据空间、域、主题、数据写入者与数据读取者这些基本术语入手。这些术语不是孤立名词,而是共同构成一张“数据如何被发现、匹配、传输与消费”的关系网。
一、核心原理:发布订阅与以数据为中心
传统点对点通信中,发送方必须知道接收方的地址、端口和协议;而 DDS 采用发布订阅模型:发布者只负责把数据写入一个逻辑主题,订阅者只声明自己关心哪个主题,中间件负责完成匹配与投递。发布者与订阅者在时间、空间和数量上完全解耦——发布者不需要知道有多少订阅者,订阅者也不需要知道数据来自哪个节点。
更关键的是 DDS 的以数据为中心(Data-Centric)特性。它关注的不是“谁在发消息”,而是“当前系统中有哪些数据对象、它们处于什么状态、谁需要这些状态”。因此 DDS 不仅传输数据,还维护数据的生命周期、历史、所有权和状态变化。例如,一个温度传感器持续更新温度值,DDS 可以只把最新值交给新加入的订阅者,而不是重放全部历史。
一句话理解:发布订阅解决“怎么传”,以数据为中心解决“传什么、当前值是什么、谁该拿到”。
二、全局数据空间、域与主题
全局数据空间(Global Data Space)是 DDS 的逻辑核心。可以把它想象成一个所有参与者共享的“数据黑板”:发布者往黑板上写数据,订阅者从黑板上读数据,而黑板本身由 DDS 域统一管理。全局数据空间不是物理服务器,而是由同一域内所有参与者共同构成的逻辑视图。
域(Domain)是全局数据空间的隔离边界。每个域有一个域 ID,只有域 ID 相同的参与者才能互相发现和通信。不同域之间默认完全隔离,这为多系统共存、测试与生产隔离提供了天然支持。例如,车辆控制域与娱乐域可以使用不同域 ID,避免误订阅。
主题(Topic)是域内数据对象的唯一标识,通常由名称和数据类型共同定义。主题是发布者与订阅者匹配的“契约”:发布者写主题 A,订阅者读主题 A,二者才能建立关联。主题名称相同但数据类型不同,通常无法匹配,甚至会导致发现失败。
三、数据写入者与数据读取者
数据写入者(DataWriter)是发布端的实体,负责把应用数据写入某个主题。它并不直接面向某个订阅者,而是面向主题。DataWriter 可以设置可靠性、持久性、历史深度等 QoS 策略,决定数据如何被写入全局数据空间。
数据读取者(DataReader)是订阅端的实体,负责从某个主题读取数据。它同样不关心数据来自哪个发布者,只关心主题是否匹配。DataReader 可以配置监听器或等待集,在数据到达时触发回调,也可以主动轮询读取。
一个参与者(Participant)可以创建多个 DataWriter 和 DataReader,分别对应不同主题。发布者与订阅者之间不是一对一,而是多对多:多个 DataWriter 可以写同一主题,多个 DataReader 可以读同一主题,DDS 根据 QoS 决定数据如何合并、过滤或替换。
四、案例场景:车载温度监控
假设一辆智能汽车中有三个节点:温度传感器节点、座舱控制器节点和云端上报节点。温度传感器创建 DataWriter,写入主题 Vehicle/Temperature;座舱控制器创建 DataReader,订阅同一主题;云端上报节点也创建 DataReader,订阅同一主题。三者处于同一个域 ID = 0 中。
Domain ID: 0
Topic: Vehicle/Temperature
Type: TemperatureData { double value; long timestamp; }
DataWriter (传感器节点) --写--> Topic --读--> DataReader (座舱控制器)
--读--> DataReader (云端上报)
QoS:
Reliability = RELIABLE
Durability = TRANSIENT_LOCAL
History = KEEP_LAST(1)
当温度从 25.0 ℃ 变为 26.5 ℃,DataWriter 发布新样本。座舱控制器和云端上报节点都会收到该样本。如果云端上报节点晚启动 2 秒,由于设置了 TRANSIENT_LOCAL 持久性,它仍能拿到最近一次温度值,而不是空等下一次更新。这就是“以数据为中心”带来的状态同步能力。
五、常见误区与复盘
- 误区一:把主题当成消息队列。DDS 主题不是队列,而是数据对象的状态通道。订阅者拿到的是当前数据状态,而不是按顺序消费的消息流。
- 误区二:认为发布者必须知道订阅者。发布订阅模型的核心就是解耦,发布者只写主题,匹配由中间件完成。
- 误区三:忽略域 ID 隔离。域 ID 不同,即使主题名称相同也无法通信,这是排障时最先检查的项之一。
- 误区四:主题名称相同但类型不同。DDS 匹配通常要求名称和类型一致,类型不一致会导致发现失败或数据无法解析。
排障提示:当订阅者收不到数据时,按顺序检查:域 ID 是否一致 → 主题名称是否一致 → 数据类型是否一致 → QoS 是否兼容(如可靠性、持久性)→ 网络发现是否正常。
六、术语速查清单
| 术语 | 英文 | 作用 | 关键点 |
|---|---|---|---|
| 域 | Domain | 隔离通信边界 | 域 ID 相同才能互通 |
| 主题 | Topic | 数据对象标识 | 名称 + 数据类型 |
| 数据写入者 | DataWriter | 发布端实体 | 面向主题写数据 |
| 数据读取者 | DataReader | 订阅端实体 | 面向主题读数据 |
| 全局数据空间 | Global Data Space | 逻辑共享视图 | 由域内参与者共同构成 |
| 发布订阅模型 | Publish-Subscribe | 通信解耦 | 时间、空间、数量解耦 |
| 以数据为中心 | Data-Centric | 关注数据状态 | 维护当前值、历史与生命周期 |
掌握这些基本术语后,后续学习 QoS 策略、发现机制、监听器和等待集时,就能把它们放到“域—主题—写入者—读取者—全局数据空间”这张关系图中理解。DDS 的工程能力,本质上就是围绕这些基本对象进行配置、匹配与排障的能力。