张勇+裴东良+张会兵
摘要:针对目前软件系统之间的消息传输解决方案中存在的缺陷,提出了一种消息传输系统,并对其核心的路由单元进行了分析和设计。此外,建立了基于队列库的动态路由机制。该消息传输系统可支持多级分布式部署的软件系统之间的消息存储转发,且部署、维护、配置、集成都极其便捷。
关键词:消息传输;路由;队列
中图分类号:TP312 文献标识码:A DOI:10.3969/j.issn.1003-6970.2016.03.013
0引言
软件系统之间的消息传输有两种解决方案:一种解决方案为:数据传输由两个软件系统之间协调完成,常用方式有Web Service;一种方案为:建立独立的消息传输系统,作为各个软件系统之间进行消息(数据)传输的桥梁,类似邮局的功能。两种方式适用范围不同。第二种方式适用了业务量大,业务软件较多、部署结构复杂的情况。
目前,对于上述第二种实现方式,一般都采用商用的消息中间件来实现,如ActiveMQ、TLQ等。但无一例外的,都需要进行二次开发,且还需要在这些消息中间件上进行手动的配置(如建立收发队列)。如果面对软件系统多、部署情况复杂的情况,这种方式则表现出部署复杂、配置共工作量大、不易维护等缺点。
针对上述情况,本文提出了一种消息传输系统,并对核心的路由单元进行分析和设计。该系统可支持多级分布式部署的软件系统之间的消息存储转发,且部署、维护、配置、集成都极其便捷。
1系统构建
消息传输系统是按照分布式部署方式进行设计的,可根据实际情况进行部署,如可按“中央一省级”两级部署,也可按照“中央一省级一市级”三级部署。理论上,部署层级是无限制的。考虑到现实情况,按照三级部署基本可满足要求,其部署结构如图1所示。在整个传输系统中,有三个角色:消息发送方系统、消息接收方系统、消息传输系统。消息发送方系统通过消息传输系统提供的API将消息发送至消息传输系统的消息接收队列;消息传输系统监听发送队列情况,发现有新到的消息则将消息取出,并进行路由计算,如果是消息接收方为同一个域内的业务系统,则直接将消息插入到消息接收方的队列中;如果消息接收方是上级域或者是同级非同域的业务系统时,则把消息转发给上级消息传输系统,由上级传输系统按照上述逻辑继续进行消息的存储转发。消息接收方监听自己的队列中是否有消息,如果有,则取走消息进行消费。
2路由机制设计
2.1路由单元结构设计
消息传输系统中的路由单元由三部分组成:路由计算模块、策略库和消息转发模块。路由计算模块负责根据接收方地址与当前消息传输系统地址进行计算,得出策略代码,并根据策略代码查找策略库,得出下一跳地址;策略库中存储的路由策略;消息转发模块负责根据下一跳地址发送给指定的接收方。
整个路由过程流程为:
(1)消息传输系统中的消息监听单元负责监听本传输系统中本地队列中的输入队列,发现消息即将此消息传递给路由计算模块;
(2)路由计算模块获取消息,并对消息进行解析,取出消息接收方(一条消息可能有多个接收方),地址并与本传输系统的地址进行计算,得出策略代码;然后根据策略代码查询策略库,得出下一跳的地址;并将消息重新包装,传递给消息转发模块;
(3)消息转发模块根据下一跳的地址将消息发送给指定的接收方。
2.2定义
为方面后续的算法说明,做以下名称和符号的定义及说明
1)消息
在消息的格式中,本文仅关注核心的消息接收方部分的内容。消息接收方分为两部分:接收方列表Dperm、临时接收方列表Dtemp。Dperm是由消息发送方在发送消息时写入的,代表了当前消息的所有接收方。Dtemp是由消息传输系统在进行消息转发时写入的,代表了消息的临时接收方。Dperm和Dtemp都是一个数组,由接收方地址组成,如下所示:
2)域名
由于消息传输系统是按照行政级别的方式进行分级部署的,每一级的应用系统都通过本级的消息传输系统进行消息的收发。因此,需要对消息传输系统的管辖范围进行定义,这就是域名(domain)的概念,用符号Dom表示,取值为国家标准的域名库。域名通过点分制的字符串来描述,每一段代表了一个行政级别,如浙江省的域名zj.cn,石家庄的域名的sjz.he.cn
3)消息队列
每个消息传输系统在部署完成后都会初始化一部分消息队列。这些消息队列分为两类:业务应用队列和系统队列。业务应用队列是与该消息传输每一类队列又分为两个子类:IN队列和OUT队列。IN队列是接收消息的队列,即消息传输系统将消息放到接收方的IN队列,接收方负责监听此队列,并在消息来到时进行消费。OUT队列是发送消息的队列,消息发送方将消息发送至自己的OUT队列,消息传输系统负责监听所有的OUT队列,并在有消息时进行消费。
4)策略
策略用一组代码来指明符合特定代码的下一跳的地址。策略用符号T表示,T是一个二元组,由策略代码、下一跳地址组成,分别使用c和N表示。如下所示:
2.3路由算法设计
(1)基本原则
消息的传输路径与消息传输系统的部署框架存在一定关系,因此,在第2章节所描述的系统部署架构的下,路由算法有两个基本原则:
1)任意两个业务系统之间不能直接收发消息,必须将消息发送给所属的消息传输系统,由消息传输系统负责完成消息的存储转发。
2)不同域的消息传输系统之间不能直接进行消息的收发,必须通过上级消息传输系统完成,如长沙的业务系统需要向杭州的业务系统发送消息时,只能通“长沙->湖南->中央->浙江->浙江”的路由进行消息转发。
(2)路由算法
1)符号定义
dpdomi:表示当前消息的第i个接收方的域名;Mdom:表示当前消息传输系统的域名
2)路由算法
在3.2节及上述定义的之下,路由算法如图3所示。
3动态路由
在前面的消息传输的分析和研究中,主要考虑消息的正向传输过程中的核心问题:消息是如何进行路由选择的,而并未考虑作为消息接收方的业务系统在整个消息传输过程中的作用。不管是接受消息的业务系统还是进行存储转发的消息传输系都具有动态调整自身接受消息策略的需求。尤其对于作为桥梁的消息传输系统。为了保证消息传输的高效性和安全性,为每个业务系统都不止分配一个接受队列。在正常的消息传输过程中,消息传输模块是按照下一跳的地址进行转发时,是随机发送到下一跳系统任意一个队列中,以用随机的方式保证各队列的负载均衡。随机性的缺陷是很明显的,如果随机选择的队列已经负载很大或者根本不可用时,就需要将当前的消息转发至其他队列中的一个,达到真正的负载均衡的效果。此外,也存在业务系统不需要接收消息的需求,此时可通知消息传输系统,不再发送消息。
针对上述需求,在第3节所述结构的基础上,增加队列库,队列的使用方及消息传输系统对队列的状态进行实时更新,消息转发模块在转发时,查询队列库,并根据各个队列的实时状态,择优选择目的队列。其结构如图4所示。
其中,队列库的结构如表2所示。每一个队列是一个三元组Q=。Code使用方的代码。Queue是队列名,队列分为两类,发送队列(OUT开头),接收队列(IN开头)。Status是状态,0表示不可用,其他值代表当前队列中待消费的消息数。业务系统仅维护自己的IN队列,即如果不需要接收消息,则设置其OUT队列的status状态为0。消息传输系统维护所有的IN和OUT队列,如果业务系统的IN队列已经设置为0,则不进行维护。队列库可以实时反映当前所有的队列的负载情况,消息转发模块在进行消息转发时,通过查询队列库,选择合适的队列进行消息的发送,均衡负载,实现动态路由。
4结论
通过对软件系统之间的消息传输方式进行分析,指出目前常用的解决方案的缺陷。针对上述缺陷,提出了一种分布式跨级的消息传输系统。在上述基础上,对消息传输系统中的核心部分一路由单元的架构进行了设计,建立了基于策略库和队列库的路由算法集。该系统的弹性部署方式可应对绝大多数的应用场景,且部署、维护、配置、集成、性能方面都有一定的优势。