本文做者:Apollo开发者社区服务器
拓扑结构是指网络中各个站点相互链接的形式,在局域网中明确一点讲就是文件服务器、工做站和电缆等的链接形式。网络的拓扑结构反映出网络中各实体的结构关系,是建设计算机网络的第一步,是实现各类网络协议的基础,它对网络的性能,系统的可靠性与通讯费用都有重大影响。网络
在P2P网络通讯中,咱们须要解决的两个首要问题就是——和谁进行通讯以及如何进行通讯。无论通讯方式是选择TCP仍是UDP,咱们都须要获取对端的一些标识,如IP和端口号等,从而创建链接。函数
本次将介绍第一点的解决方式:参与者的标识和参与者的互相发现。性能
如下,ENJOY 学习
在Cyber RT中,咱们将主要通讯角色(Role)分为:spa
Node。计算机网络
Reader/Writer。设计
Server/Client。指针
每一个角色使用RoleAttributes进行标识。其中,Reader/Writer以及Server/Client都是在Node中建立的,Reader和Writer能够经过Channel进行三种方式的通讯,Server经过Service向Client提供服务。所以,Cyber RT中的拓扑就是指各通讯角色的位置、发布/订阅等信息。接口
咱们能够经过使用有向图来抽象整个系统中的角色和它们之间的关系。其中,Reader/Writer和Server/Client能够用图的顶点表示,Node则在逻辑上对这四种角色进行包含。图的边咱们用Channel表示,Channel从Writer流向Reader,表示Writer/Reader的发布/订阅关系。实际上,Server和Client也是经过Channel进行通讯的。这在Cyber RT中被称为系统的拓扑(Topology)结构。赋予各个角色以惟一标识,并使用Channel同其它系统中的角色进行通讯,这就是拓扑发现。
所以,拓扑发现主要用来获取整个系统中各个角色的分布:
整个系统建立的Node,以及这些Node建立的Writer/Reader/Server/Client。
使用某个Channel进行通讯的Writer/Reader。
和某个Service相关联的Server/Client。
拓扑发现主要有两种方式:
静态拓扑发现。在配置文件中事先指定各Writer/Reader和Channel等的对应关系。该方法的优势是拓扑发现迅速,缺点则是配置缺乏灵活性。
动态拓扑发现。
动态拓扑发现又分为如下两种:
中心化的拓扑发现。启动一个名字发现服务做为中心点,当建立Node等角色时,向这个服务进行注册,并获取已有的全部角色信息,同时,Server须要向已有的注册节点发送更新消息。这种方式容易出现单点问题,而且因为长链接的创建,会致使系统资源的负载增大。
去中心化的拓扑发现。采用广播或者组播的方式,向系统中的其它参与者报告本角色的加入/退出。这种方式解决了单点问题,同时减小了链接量,可是当节点同时加入时,容易产生广播风暴。
综合考虑,Cyber RT使用动态的去中心化拓扑发现,采用第三方eProsima Fast RTPS进行通讯管理。使用该库的组播接口,经过设置CYBER_DOMAIN_ID(能够转换成整形的字符串)来创建一个DOMAIN,不一样DOMAIN之间的通讯不会互相干扰。咱们能够利用该特性,经过设置不一样的Domain ID,来在同一台机器中运行多套Cyber RT系统。
Cyber RT建立了如下几个拓扑管理者:
NodeManager:主要用来管理和查询整个系统中的Node。
ChannelManager:主要管理和查询Channel相关的拓扑,涉及到Node/Writer/Reader。咱们能够从中获取到一个Channel的全部Writer/Reader,能够根据一个Channel是否有相应的Reader来判断对端是否已经初始化完成,以准备发送数据等。
ServiceManager:主要用来管理和查询整个系统中的Server和Client。
其中:
NodeManager和ServiceManager中节点存储比较简单,使用Role-ID和RoleAttributes映射的map存储便可。
ChannelManger包含了Channel相关的Node/Writer/Reader的存储。能够用来查询Node建立以及和Channel有关的全部Writer/Reader。
另外,咱们使用有向图(Directed Graph)进行拓扑中Node相关角色的存储。图的边(Edge)为Channel名称,图的顶点(Vertice)为Node。
两个Node间主要有如下三种关系:
UPSTREAM:若是Node A中有Channel C的Writer,而Node B中有Channel C的Reader,那么Node A被叫作Node B的上游。
DOWNSTREAM:若是Node A中有Channel C的Reader,而Node B中有Channel C的Writer,那么Node A被叫作Node B的下游,两个Node能够互为上下游。
UNREACHABLE:Node A和Node B没有Channel相关联。
你能够经过TopologyManager的AddChangeListener来监听整个系统中拓扑的变化。
拓扑发现主要处理两个动做:
Join。一个角色加入拓扑。
Leave。一个角色离开拓扑。
这两个动做都须要被组播给相同Domain中的其它角色,而且,其它角色的历史动做也须要被新加入角色所熟知。为此创建以下的拓扑发现流程:
初始化TopologyManager,建立RTPS的Participant,这相似于Cyber RT的Node,能够用来建立拓扑消息的Publisher和Subscriber。同时注册一个对端Participant变更的回调——OnParticipantChange。
每一个进程建立上述三种Manager,该Manager会建立对应的Publisher和Subscriber(使用的Channel名称为*_change_broadcast)。设置Publisher的QOS策略为HISTORY_KEEP_ALL,这样,当有其它进程建立拓扑的Subscriber时,本进程发送过的拓扑Join或者Leave消息将会发送给新加 入的节点,保证整个拓扑的连续性和完整性。
当建立Node、Writer/Reader、Server/Client时,调用对应Manager的Join函数,请求加入拓扑。同时,因为上述QOS的设置,咱们会收到其它进程的历史拓扑消息。
当收到其它角色的拓扑加入请求时,更新本地拓扑结构。Cyber RT要求每一个Node拥有惟一的命名,若是在拓扑里发现同名Node,则比较二者的时间戳,时间戳小的Node保留。
当一个Participant退出时(OnParticipantChange被调用),将该Participant相关的拓扑从本地移除。
根据拓扑中的主机IP和进程名称,咱们能够对一个Channel的Writer和Reader进行关系划分,以采用恰当的通讯方式,提升通讯效率。
NO_RELATION:这两个Writer和Reader之间没有直接关系,也就是它们不是共用的一个Channel。
DIFF_HOST:不一样主机,不一样主机间的Writer和Reader只能使用RTPS进行通讯。
DIFF_PROC:同一主机,不一样进程。同一主机不一样进程既可使用RTPS进行通讯,也可使用共享内存的方式。默认为共享内存通讯方式,能够经过配置进行更改。
SAME_PROC:同一进程的Writer和Reader直接使用指针传参的方式进行通讯。
同时,咱们能够经过拓扑查询某些节点的存活状态、验证整个DAG图是否完整。
另外,拓扑消息中还会夹带Channel的proto_type,proto_desc等用于消息序列化/反序列化。
本文从对“拓扑”概念开始,对“和谁进行通讯”问题进行了解答。阿波君向你们介绍了三种通讯角色,同时扩展了拓扑管理者的做用。最重要的是详细地解释了拓扑发现方式、发现流程及拓扑发现的应用。
阅读完今天的文章,热爱学习的你是否对Cyber RT拓扑发现有了进一步的了解呢?关于“如何进行通讯”你又有怎样的疑惑和认识呢?