DDS是一套通信协议和API标准,它提供了以数据为中心的连接服务。Fast-RTPS是DDS的开源实现,借助它可以方便的开发出高效,可靠的分布式系统。本文是对DDS以及Fast RTPS的介绍文章。
从《变形金刚》电影说起
这里要提到的是2011年的真人版电影,变形金刚第三部《Transformers: Dark of the Moon》。
这是一篇技术文章,为什么要扯到《变形金刚》电影呢?这是因为这部电影的主要内容与本文所提到的技术有一定的相关性。
在这部电影中,御天敌背叛了擎天柱,与霸天虎合作。在地球的各地布置了许多的能量柱,他试图借助这些能量柱将赛博坦星球传送到地球上,以此来重建自己的家园。
这些能量柱必须组合起来才能完成传输工作,并且在这其中有一个红色的能量柱比较特殊,因为它负责控制其他的传送柱。
由此可见,这是一个大型的分布式系统。在这个系统中,这个红色的能量柱被称之为“中心节点”,中心节点正如其名称那样,它是整个系统的中心。对于带有中心节点的分布式系统来说,一旦中心节点被摧毁,整个系统都将无法工作。
因此电影的后来,自然是擎天柱摧毁了这个中心节点,使得御天敌的传送计划彻底失败。
从设计上来说,对于一个如此大型的系统,却存在一个非常薄弱和重要的中心节点,这并不是一个好的方案。
而本文介绍的DDS就是一个去中心化的分布式技术。因此在这类系统中,不存在负责总控制的中心节点,所有节点都完全对等。任何一个节点的异常都不会影响整个系统的运行。
DDS介绍
DDS全称是Data Distribution Service,这是一套通信协议和API标准,它提供了以数据为中心的连接服务,基于发布者-订阅者模型。这是一套中间件,它提供介于操作系统和应用程序之间的功能,使得组件之间可以互相通信。并且提供了低延迟,高可靠的通信以及可扩展的架构。
或许,你已经知道很多种网络通信协议,对于发布-订阅这些概念也很熟悉。那DDS到底有什么特别之处呢?
下图展示了4个时代的数据通信方式:
- (第一代)点对点的CS(Client-Server)结构,这是大家最为熟悉的:一个服务器角色被许多的客户端使用,每次通信时,通信双方必须建立一条连接。当通信节点增多时,通信的连接数也会增多。并且,每个客户端都必须知道服务器的具体地址和所提供的服务。一旦服务器地址发生变化,所有客户端都会受到影响。
- (第二代)Broker模型:存在一个中间人,它负责初步处理大家的请求,并进一步找到真正能响应服务的角色,这就好像存在一个经纪人。这为客户端提供了一层抽象,使得服务器的具体地址变得不重要了。服务端地址如果发生变化,只需要告诉Broker就可以了。但这个模型的问题在于,Broker变成了模型的中心,它的处理速度会影响所有人的效率,这就好像城市中心的路口,当系统规则增长到一定程度,Broker终究会成为瓶颈。更糟糕的是,如果Broker瘫痪了,可能整个系统都将无法运转。
- (第三代)广播模型:所有人都可以在通道上广播消息,并且所有人都可以收到消息。这个模型解决了服务器地址的问题,且通信双方不用单独建立连接,但它存在的问题是:广播通道上的消息太多,太嘈杂,所有人都必须关心每条消息是否与自己有关。这就好像全公司一千号人坐在同一个房间里面办公一样。
- (第四代)DDS模型:这种模型与广播模型有些类似,所有人都可以在DataBus上发布和读取消息。但它更进一步的是,通信中包含了很多并行的通路,每个人可以只关心自己感兴趣的消息,自动忽略自己不需要的消息。
下图展示了DDS在网络栈中的位置,它位于传输层的上面,并且以TCP,UDP为基础。
这个图之所以是沙漏形状是因为:两头的技术变化都发展很快,但是中间的却鲜有变化。
对比大家常见的Socker API,DDS有如下特点:
特性 | Socket API | DDS |
架构 | TCP:点对点 UDP:点对点,广播,多播 |
Publish-subscribe模型 |
平台独立 | 需要为不同硬件,操作系统和编程语言编写不同的代码 | 所有硬件,操作系统和编程语言使用相同的API |
发现 | 需要硬编码IP地址和端口号 | 动态发现,无需关注端点所在位置 |
类型安全 | 没有类型安全,应用需要将字节流转换成正确类型 | 强类型安全,write() 和read() 针对特定数据类型 |
通信行为定制 | 需要通过自定义的代码来实现 | 通过QoS策略来完成 |
互操作性 | 不支持 | 具有公认的互操作性的开放标准 |
关于DDS的更多特性,可以点击这个链接:《What is DDS?》。
DDS可以降低系统复杂度
对于分布式系统来说,有很多复杂的逻辑需要处理,例如:如何发现其他节点,如何为每个节点分配地址,如何配置消息的可靠性等。这使得应用程序变得臃肿。
而如果说通信的中间件能够完全处理好这些逻辑,则应用程序将可以集中处理自己的业务,变得更加敏捷。
下图是两种情况的对比:
如果考虑系统的演化,问题会更突出。
由于分布式系统中包含了许多的角色需要互相通信,随着角色数量的不断增长,其通信的通道数量会以爆炸式增长。
而如果有统一的DataBus,则即便新增了通信角色其通信模型也不会变得更加复杂。
DDS应用范围
尽管可能你原先没有听过DDS这个术语,但其实它的应用非常广泛,广泛到它涉及到了我们每天都要依赖的许多重要行业,例如:航空,国防,交通,医疗,能源等等。
下图是一些示例:
DDS 提供商
DDS本身是一套标准。由Object Management Group(简称OMG)维护。
OMG是一个开放性的非营利技术标准联盟,由许多大型IT公司组成:包括IBM,Apple Computer,Sun Microsystems等。
但OMG仅仅负责制定标准,而标准的实现则由其他服务提供商完成。
目前DDS的提供商包括下面这些:
- Vortex OpenSplice
- eProsima Fast RTPS
- Hamersham
- Company Summary Kongsberg Gallium
- MilSOFT
- Object Computing OpenDDS
- Remedy IT
- RTI
- Twin Oaks Computing, Inc.
DDS与RTPS
在DDS规范中,有两个描述标准的基本文档:
- DDS Specification:描述了以数据为中心的发布-订阅模型。该规范定义了API和通信语义(行为和服务质量),使消息从消息生产者有效地传递到匹配的消费者。DDS规范的目的可以概括为:“能够在正确的时间将正确的信息高效,可靠地传递到正确的位置”。
- DDSI-RTPS:描述了RTPS(Real Time Publish Subscribe Protocol)协议。该协议通过UDP等不可靠的传输,实现最大努力(Best-Effort)和可靠的发布-订阅通信。RTPS是DDS实现的标准协议,它的目的和范围是确保基于不同DDS供应商的应用程序可以实现互操作。
DDS与汽车行业
对于汽车行业来说,汽车开放系统架构(AUTomotive Open System ARchitecture)已经在AUTOSAR Adaptive Platform 18.03中包含了DDS协议。
ROS2架构也以DDS为基础。
另外,DDS的实时特性可能特别适合自动驾驶系统。在这类系统中,通常会存在感知,预测,决策和定位模块,这些需要非常高速和频繁的交换数据。借助DDS,可以很好的满足它们的通信需求。
Fast-RTPS 介绍
Fast-RTPS是eprosima对于RTPS的C++实现,这是一个免费开源软件,遵循Apache License 2.0。
eProsima Fast RTPS在性能,功能和对最新版本RTPS标准(RTPS 2.2)的遵守方面均处于领先地位。关于Fast RTPS的性能可以查看这个链接:eProsima Fast RTPS Performance。
它最为被大家知道的可能是因为被ROS2设定为默认的消息中间件。
Fast-RTPS支持平台包括:Windows, Linux, Mac OS, QNX, VxWorks, iOS, Android, Raspbian。
Fast-RTPS具有以下优点:
- 对于实时应用程序来说,可以在Best-Effort和可靠通信两种策略上进行配置。
- 即插即用的连接性,使得网络的所有成员自动发现其他新的成员。
- 模块化和可扩展性允许网络中设备不断增长。
- 可配置的网络行为和可互换的传输层:为每个部署选择最佳协议和系统输入/输出通道组合。
- 两个API层:一个简单易用的发布者-订阅者层和一个提供对RTPS协议内部更好控制的Writer-Reader层。
源码与编译
Fast-RTPS的源码位于Github上:eProsima/Fast-RTPS。
可以通过下面这条命令获取其源码:
git clone https://github.com/eProsima/Fast-RTPS.git
关于如何编译Fast-RTPS可以参见这个链接:Fast RTPS Installation from Sources。
Fast-RTPS概述
Fast-RTPS提供了两个层次的API:
- Publisher-Subscriber层:RTPS上的简化抽象。
- Writer-Reader层:对于RTPS端点的直接控制。
相较而言,后者更底层。两个层次的核心角色如下图所示:
Publisher-Subscriber层为大多数开发者提供了一个方便的抽象。它允许定义与Topic关联的发布者和订阅者,以及传输Topic数据的简单方法。
Writer-Reader层更接近于RTPS标准中定义的概念,并且可以进行更精细的控制,但是要求开发者直接与每个端点的历史记录缓存进行交互。
Fast RTPS是并发且基于事件的。每个参与者都会生成一组线程来处理后台任务,例如日志记录,消息接收和异步通信。
事件系统使得Fast RTPS能够响应某些条件并安排定期活动。用户中几乎不用感知它们,因为这些事件大多数仅仅与RTPS元数据有关。