介绍
也许应用程序设计人员在创建分布式系统时面临的最关键决策之一是如何在感兴趣的各方之间交换数据。通常,这涉及选择一个或多个通信协议并确定向每个端点分派数据的最有效手段。实现较低级别的通信软件可能是耗时的,昂贵的并且容易出错。很多时候,经过大量的时间和精力投入后,许多设计师发现最初设计中的最后一刻需求变化或缺陷会浪费在这个关键的软件层上。
中间件解决方案旨在帮助(如果不能解决)这些类型的问题。设计人员可以依赖于给定中间件产品中存在的功能来充当事实上的兼容层,而不是让每个应用程序实现自定义通信套件。数据分发服务(DDS)规范是对象管理组提出的一种解决方案。如 前一篇文章所述,OpenDDS是DDS规范的开源实现,它提供了许多可插拔的传输选项,以满足各种通信需求。结合富有表现力的服务质量(QoS)设施,OpenDDS是那些需要可配置且高效的数据分发方式的项目的理想解决方案,设计人员几乎没有风险。
从版本2.1开始,OpenDDS提供了一种新的IP多播传输,在有损网络上具有更高的可靠性和更好的确定性。本文详细介绍了多播传输实现,它在基于IP的网络上的交互,以及OpenDDS支持的其他基于IP的传输的比较分析。
履行
从版本2.1开始,multicast
传输提供对IP多播的支持 。该 multicast
运输被设计为旧的ReliableMulticast
和 SimpleMcast
运输的替代品 。与其他OpenDDS传输实施不同, multicast
它为基于传输配置的尽力而为可靠的传送提供统一支持。
尽管在同行之间交换数据,但尽力交付会产生最少的开销,但是它不提供任何交付保证。数据可能由于无响应或无法访问的对等方丢失或一式两份收到。
可靠的传送提供了保证向关联对等方传送数据而不会以额外处理和带宽为代价进行重复。通过两种主要机制实现可靠的交付:双向对等握手和对缺失数据的否定确认。这些机制中的每一个都是有限的,以确保确定性行为,并且可配置以确保用户环境可能的最广泛的适用性。
通过两个主要机制实现可靠的交付:
- 双向对等握手(SYN / SYN + ACK)
- 对缺失数据的否定确认(NAK / NAK + ACK)
为了讨论可靠对等体之间的交互,有助于将多播组的视图缩小到两个特定对等体:主动和被动。该活性对等体是一个关联的发布侧。在被动同行总是订阅同行。重要的是要记住控制数据在多播组内的所有对等体之间交换; 然而,不感兴趣的同伴会丢弃直接向他们发送的有效载荷。
同行握手(SYN / SYN + ACK)
用于确保可靠性的第一种机制是相关对等体之间的双向握手。握手机制提供了给定对等体等待形成关联多长时间的确定性约束。此功能还用于防止发布对等方过早发送数据。这种机制详述如下:
活动(即发布MULTICAST_SYN
者)对等体通过以超时限制的周期性间隔向被动(即订户)对等体发送控制样本来发起握手, 以确保传送。基于重试次数观察到指数退避。
在接收到 MULTICAST_SYN
对照样本后,被动对等体记录活动对等体的当前传输序列值并用MULTICAST_SYNACK
对照样本进行响应 。该序列号建立了一个值,从该值可以在将来识别接收间隙。
如果活动对等体接收到 MULTICAST_SYNACK
控制样本,则它通知应用程序该关联已完成。如果 MULTICAST_SYNACK
未收到控件样本,则会记录错误。
否定确认(NAK / NAK + ACK)
否定确认是确保数据可靠性的主要机制。该机制将检测数据丢失的责任放在每个订户上,这允许发布者尽可能快速有效地分派数据。这种机制详述如下:
当每个数据报被传递给被动对等体时,传输序列值针对识别接收间隙的特殊容器进行评分。通过重置序列低水位标记并记录错误,监视程序定期执行并使最旧的未完成修复请求老化。一旦清除了未完成的请求,监视器就会检查接收间隙。如果识别出新的(或现有的)接收间隙,则对等体记录传输序列的当前间隔和高水位标记。然后 MULTICAST_NAK
,它将控制样本发送到缺少数据的活动对等体。被动对等体基于发往同一活动对等体的所有修复请求来执行NAK抑制。如果以前 MULTICAST_NAK
请求已由其他被动对等体发送,被动对等体暂时省略当前间隔的先前请求的范围。该间隔是随机的,以防止类似关联的对等体之间的潜在冲突。
如果活动对等体接收到 MULTICAST_NAK
控制样本,则检查其发送缓冲区以查找丢失的数据报。如果数据报不再可用,它会将MULTICAST_NAKACK
控制样本发送 到整个多播组以抑制进一步的修复请求。如果数据报仍然可用,它会将丢失的数据重新发送到整个多播组。
如果被动对等体接收到 MULTICAST_NAKACK
控制样本,则其行为就像修复请求已经老化一样,从而抑制了进一步的修复请求并记录了错误。
组态
该 multicast
运输支持许多配置选项:
- 在
default_to_ipv6
和port_offset
选项会影响组播组地址的方式默认选中。如果
default_to_ipv6
设置为1
(启用),则使用默认IPv6地址。该port_offset
选项确定使用的默认端口;此值将添加到传输ID以确定实际端口号。默认值分别为0
(禁用)和49400
。 - 该
group_address
选项可用于手动定义要加入的多播组以交换数据。支持IPv4和IPv6地址。与此同时SimpleTcp
,OpenDDS IPv6支持要求在启用IPv6支持的情况下构建基础ACE / TAO组件。224.0.0.128:
IPv4和[FF01::80]:
IPv6 的默认值 。 - 如果需要可靠的交付,则
reliable
可以指定选项。其余配置选项会影响多播传输使用的可靠性机制。默认值为1
(启用)。 syn_backoff
,syn_interval
和syn_timeout
配置选项会影响握手机制。syn_backoff
是计算重试之间的退避延迟时使用的指数基数。该syn_interval
选项定义重试握手之前等待的最小毫秒数。该syn_timeout
定义millseconds
的最大数量的握手放弃之前等待。默认值分别为2.0
,250
和30000
(30秒)。- 给定的值
syn_backoff
和syn_interval
,可以计算握手尝试之间的延迟(由界定syn_timeout
):
delay = syn_interval * syn_backoff ^ <#retries>
例如,如果假定默认配置选项,则握手尝试之间的延迟将为:0,250,1000,2000,4000,8000和16000毫秒。
nak_depth
,nak_interval
和nak_timeout
配置选项影响否定确认机制。nak_depth
确定传输为传入的修复请求提供服务所保留的最大数据报数。该nak_interval
配置选项定义毫秒的最小数量的维修请求之间等待。该间隔是随机的,以防止类似关联的对等体之间的潜在冲突。修复请求之间的最大延迟限制为最小值的两倍。该nak_timeout
配置选项定义的时间放弃之前等待修理请求的最大数量。默认值分别为32
,500
和30000
(30秒)。
为方便起见,OpenDDS发行版中的以下位置提供了一个示例.ini文件: $DDS_ROOT/dds/DCPS/transport/multicast/multicast.ini-dist
目前,使用传输时必须遵守一些限制:
- 最多,每个唯一的多播组可以仅由一个DDS域使用。
- 给定
DomainParticipant
对象可能仅为特定多播组附加一个多播传输。例如,对于aPublisher
和Subscriber
从同一DomainParticipant
对象创建 的应用程序,应用程序可能不会在传输中使用相同的多播组 。如果应用程序希望在同一进程中同一组播组上发送和接收样本,则应用程序必须DomainParticipant
为同一个域创建两个不同的 对象 - 一个用于Publisher
,另一个用于Subscriber
。
与其他传输一样,ACE Service Configurator Framework也启用了动态配置。一个 svc.conf
文件应该被创建了包含以下内容:
dynamic OpenDDS_DCPS_Multicast_Service Service_Object *
OpenDDS_Multicast:_make_MulticastLoader()
通过将以下参数传递给应用程序的命令行,在运行时加载传输:
-ORBSvcConf svc.conf
或者,可以通过包含dds/DCPS/transport/multicast/Multicast.h
标头(暗示静态链接)静态加载传输 :
#ifdef ACE_AS_STATIC_LIBS
# include <dds/DCPS/transport/multicast/Multicast.h>
#endif
最后,多播传输的配置和附加方式与其他传输实现类似:
OpenDDS::DCPS::TransportImpl_rch transport_impl =
TheTransportFactory->create_transport_impl(
OpenDDS::DCPS::DEFAULT_MULTICAST_ID,
OpenDDS::DCPS::AUTO_CONFIG);
OpenDDS::DCPS::AttachStatus status = transport_impl->attach(...);
if (status != OpenDDS::DCPS::ATTACH_OK) {
exit(EXIT_FAILURE);
}
互动
在讨论有线协议时,提供协议交互的图形表示通常很有帮助。如上所述,protcol状态机使用四种传输控制样本类型:
MULTICAST_SYN
MULTICAST_SYNACK
MULTICAST_NAK
MULTICAST_NAKACK
下面提供这些PDU的示例。这些数据包是使用odds_dissector Wireshark插件从SunOS(SPARC)工作站捕获的,该 插件在OpenDDS 2.1.1版中提供:
MULTICAST_SYN
控制样本从活动(即发布者)对等体发送。这些样本声明了与特定被动对等体形成关联的意图。被动对等体由最后四个八位字节标识(以蓝色突出显示)。此值对应于被动对等方的源ID。
MULTICAST_SYNACK
控制样本从被动(即用户)对等体发送。发送这些样本以确认活动对等体的握手尝试。收到后,由最后四个八位字节标识的活动对等体(以蓝色突出显示)完成与被动对等体的关联。此值对应于活动对等方的源ID。
MULTICAST_NAK
控制样本从被动对等体发送。当识别出接收间隙时,发送这些样本。以蓝色突出显示的八位字节表示缺少数据的活动对等体的源ID。以紫色突出显示的以下四个八位字节表示缺少数据的范围。前两个八位字节表示缺失范围的下限,而后两个八位字节表示上限。这些值对应于数据报的序列号。
MULTICAST_NAKACK
控制样本从活动对等体发送。当无法满足维修请求时,将发送这些样本。最后两个八位字节(以紫色突出显示)表示可以恢复的第一个数据报的序列号。
对照
构建了一个非正式测试来展示IP多播通信的可扩展性方面。扩展测试(作为OpenDDS-Bench基准测试框架的一部分提供 $DDS_ROOT/performance-tests/Bench)
收集用于将样本传播到一个或多个端点的延迟度量。使用 multicast
针对udp
(UDP / IP)和 SimpleTcp
(TCP / IP)传输的可靠和尽力而为的传送模式测试 传输。下图表示通过交换式以太网网络在八个类似配置的主机之间运行扩展测试时收集的结果:
值得注意的是,不应将这些测试运行中收集的绝对数字用作比较基础。相反,应该使用每个数据点之间的相对差异。
与单播IP传输相比, udp
是唯一一种在multicast
延迟方面表现优于 传输的传输(注意,延迟随着单播的订阅端点数量线性增加)。一旦订阅进程的数量大于2,则调度多播数据因素的一般开销。这表明在这种特定硬件上仍应考虑单播传输的两个或更少的扇出。需要注意的一点是可靠和尽力交付模式之间的相对差异。可靠性确实会产生少量开销,但是与基于单播的传输相比,所述开销不会相对于订户数量线性增加。
上述结果很好地表明何时应该认为IP多播通信是可行的。鉴于发布者可能具有多个(即多于两个)订阅端点的情况,IP多播在分派数据时提供最低延迟。相反,在发布者仅维护一个或两个订户的情况下,IP多播不太可能很好地扩展。
概要
本文详细介绍了OpenDDS 2.1版中提供的新IP多播传输。该 multicast
运输为那些谁愿意派遣可靠低延迟数据到一个或多个用户的设计理想的解决方案。虽然IP多播通信在管理可靠性方面存在许多限制因素,但我们已经证明,仍然可以以最小的开销实现可靠的通信 - 特别是随着用户数量的增加。OpenDDS由OCI专业开发和商业支持,OCI是一家提供全方位服务的软件工程,开源产品和培训公司。
参考
- OpenDDS简介
http://www.opendds.org/Article-Intro.html - 数据分发服务(DDS)规范
http://www.omg.org/spec/DDS/1.2/ - OpenDDS
multicast
设计文档 - OpenDDS Bench用户指南
****** 有对DDS技术了解,学习,开发和培训需求的,请加入QQ群:707895641(DDS专业技术辅导) ******