一种增加消息队列模型的发布/订阅系统及其工作方法与流程

文档序号:12603714阅读:1937来源:国知局
一种增加消息队列模型的发布/订阅系统及其工作方法与流程
本发明涉及一种分布式消息中间件中增加消息传递模型的技术方案,确切地说,涉及一种增加消息队列模型的发布/订阅系统及其工作方法,属于消息处理和分布式的消息中间件的技术领域。

背景技术:
首先介绍本发明涉及的相关术语:分布式计算:近年提出的一种新的计算方式,简单来讲,就是将原本由一台计算机解决的问题分配给多台计算机共同完成。具体实现方式是:将一个需要大量计算的任务分成许多子任务,然后把这些子任务分配给许多计算机分别处理,最后综合所有子任务的处理结果而得到最终结果。这些计算机可以分布在不同的地理位置,它们通过计算机网络互相通信,实现信息和资源的共享。消息中间件:一种软件或硬件的基础设施,用来支持分布式系统中消息传送。消息中间件充当着“代理人”的角色,消息生产者和接收者无需直接交互而只是与“代理人”:消息中间件进行通信,从而实现消息生产者和接收者在空间和时间上的解耦。消息中间件利用高效可靠的消息传递机制执行与平台无关的数据交流,通过提供不同的消息传递模型来扩展分布式系统中进程间的通信。消息传递模型:作为一种面向网络的通信架构模型,消息传递模型用于描述在消息传递系统中两个不同部件相互间如何连接和通信。消息传递模型有多种,早期有MessagePassing、RPC和Notifications,现在比较主流的是两种:消息队列(MessageQueueing)和发布/订阅(Pub/Sub)。消息队列模型:在计算机科学中,消息队列是一种进程间通信或同一进程的不同线程间的通信方式。消息队列模型提供了异步的通信协议,可以使通信参与者在空间和时间上解耦。消息的生产者和消费者无需直接通信,消息被发送到一个队列进行保存,直到消费者从这个队列中取走消息。在消息队列模型中,每一条消息只会被一个消费者消费,即一条消息有且只被消费一次。发布/订阅模型:其与消息队列模型有很多相似之处,它也能使得通信参与者在空间、时间完全解耦。在发布/订阅模型中,发布者(消息生产者)不会将消息直接发送给特定的订阅者(消息接收者),而只需将消息发送到消息中间件,其余的消息传送工作全部交给消息中间件完成。订阅者只需要向消息中间件发出一个订阅条件,然后,消息中间件就会将所有满足该订阅条件的新发布消息传递给订阅者。在消息消费层次上,发布/订阅模型与消息队列模型的最大不同在于:一条消息可能会被多个订阅者消费,即一条消息可以被消费任意次。发布/订阅系统:主要有两种:基于主题和基于内容。在基于主题的发布/订阅系统中,消息被归类为一个个主题(类似“组”的概念)。发布者在发送消息时会指定发送到哪一个主题,订阅者在发出订阅条件时也需要指定订阅哪些主题。另外,订阅者在订阅成功后,将接收到其订阅主题下所有新发布的消息。推模式与拉模式:发布/订阅系统中将新消息通知订阅者的方式有两种:推模式和拉模式。在推模式系统中,当有新消息产生时,系统会主动将新消息实时推送给对应的订阅者。这些新消息会实时地发送到订阅者处以某种形式缓存起来,以便订阅者在将来某个时间从缓存中获取这些消息。在拉模式系统中,当有新消息产生时,系统不会主动将新消息推送给订阅者,而是由订阅者自己向系统发出请求来拉取新消息。消费者集群:在消息队列模型中,每个队列可以有单个消费者,也可以有多个消费者。当有多个消费者时,这些消费者就组成了一个消费者集群。集群中的消费者彼此合作,共同接收同一个队列中的所有消息;但是,队列中的任意一条消息有且只被消费者集群中的一个消费者消费。哈希表:又称散列表,是一种用来存储数据的数据结构。在哈希表中,数据项以键-值对的方式存储,每一条数据项都对应一个关键字(即键值),查找数据时根据关键字来实现快速直接访问。进程:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动。每个应用程序由一个或多个进程组成,而每个进程又可由一个或多个线程组成。每个进程在执行过程中拥有独立的内存单元,这些内存单元由这个进程下的所有线程共享。线程:操作系统能够进行运算调度的最小单位。线程存在于进程中,共享同一进程的所有资源。每个线程是指进程中一个单一顺序的控制流,线程之间相互独立,并发执行不同的任务。锁:在计算机科学中,锁是一种协调多个线程对同一资源竞争访问的机制。锁类似为一种权限,持有锁,就相当于持有访问相关资源的权限。每个资源都有一把锁,只有获得这把锁的线程才能访问该资源,其余未获得锁的线程,只能等待。当持有锁的线程释放锁时,所有想获得该锁的线程通过竞争去获得这把锁。因为每个资源只有一把锁,所以任何时刻都只有一个线程能持有这把锁,即任何时刻只有一个线程能够访问这个资源,从而协调多个线程对资源的访问。众所周知,在分布式系统中,系统各组件间的通信通常是由消息中间件来完成的。消息中间件为分布式系统提供消息传递服务,保证组件间消息传递的高效性和可靠性。消息中间件在传递消息时可以遵循多种消息传递模型,其中当今较受欢迎的模型有两种:发布/订阅模型与消息队列模型。但是,由于发布/订阅和消息队列两种模型在语义上的差别,要在一个消息中间件中同时实现这两种模型比较困难,而且,即使实现了,也很难同时保证其稳定性和可靠性。然而,用户在开发业务系统时,确实存在对不同消息模型的需求。如消息推送需要使用发布/订阅模型,任务调度则需要使用消息队列模型。另外,随着用户业务系统的不断扩展,用户在不同时期可能对消息模型也会有不同需求。但消息中间件属于基础性服务,一经使用是很难、甚至是不可能变换的,所以用户需要使用不同的消息传递模型时,不得不额外添加消息中间件来满足业务需求。在实际环境中,基于分布式系统的消息中间件通常需要部署多台服务器,从而能够对外提供可扩展的、高可用的和高性能的消息传递服务。在这种情况下,如果要同时使用两种支持不同消息传递模型的消息中间件,考虑到消息服务端对系统资源的大量占用,就需要部署两个彼此独立的消息服务端集群。这样做,从系统开发角度来看,一定程度上增加了开发难度;从用户角度来看,既增加了设备投资的经济费用,还要增加维护成本。目前,在分布式消息中间件的技术领域中,比较成熟的项目还比较少。来自国外的有:由LinkedIn贡献到Apache的Kafka和由Yahoo!贡献到Apache的Hedwig,这两个系统都是基于主题的发布/订阅系统。来自国内的项目仅有基于Kafka思想研发开源到Github上的Metamorphosis,而且,相对于国外的上述两个项目,其得到的关注非常小。Kafka使用拉模式、即消费者主动向系统拉取消息的方式来实现消息分发,结合其对消费者本身的设计,Kafka提供了极大的灵活性,使消费者能够自由地选择获取队列中某一条消息,而不是被动接受。Hedwig则使用推模式、即系统主动向消费者推送消息的方式来实现消息分发,这种模式使性能和资源利用率都能够很轻易地达到一个比较高的水平,同时还使客户端的控制逻辑相对简单,更具透明性。因为本发明系统是在基于主题的发布/订阅系统中增加消息队列传递模型,组成一个能够同时支持发布/订阅和消息队列两种传递模型的消息中间件系统。因此,先介绍现有技术的基于主题的发布/订阅系统的结构组成和基本情况。在基于主题的发布/订阅系统中,消息被归类成不同的主题,并以主题为单位进行发布和订阅。发布者是消息的生产者,可以往不同的主题生产消息;且其在发布消息时,需要设定发布到哪个主题。订阅者是消息的消费者,可以接收自己感兴趣的消息,但订阅者必须先订阅自己感兴趣的主题,然后才能接收已订阅主题的新消息。所有发布到某个主题的消息都会被所有已经订阅该主题的订阅者接收,即一条消息会被多个消费者消费。该系统主要包括服务端和客户端两部分,参见图1,具体介绍基于主题的发布/订阅系统的结构组成:客户端,作为消息的发布者和订阅者,负责向服务器端发送设定主题的消息以及接收来自服务器端中已订阅主题的新消息。设有下述四个功能模块:数据通信模块,是客户端的最底层模块,负责接收所有来自服务器端的数据,并传送给响应处理模块;同时将所有来自客户端的数据发送至网络,以供传送给服务器端。响应处理模块,负责处理来自数据通信模块的、包括服务器端对客户端发布请求和订阅请求的处理响应(处理成功或失败),以及服务器端发送给订阅者的主题消息的所有数据,并传送给相应模块:若是请求的处理响应数据,则传送给发布订阅接口模块;若是主题消息数据,则传送给消息处理模块。发布/订阅接口模块,用作用户发布消息和订阅主题的交互接口,再将发布请求和订阅请求经由数据通信模块传送到服务器端;设有消息发布者和消息订阅者两个接口单元:消息发布者接口单元用于将消息发布到不同主题,消息订阅者接口单元用于向用户提供订阅感兴趣的主题。消息处理模块,负责接收与消费服务器端发来的主题消息,并对已消费消息向服务器端返回确认信号;设有三个功能单元:消息缓存单元负责将响应处理模块发送来的主题消息数据进行缓存,直到该消息被真正消费时被取出;消息消费单元负责在用户真正消费时从缓存单元取出主题消息;消息确认单元负责对已消费消息向服务器端返回确认信号。服务端,作为该系统的控制中枢,负责接收消息发布者发送来的消息,并将该消息存储到对应的主题,以及将已订阅主题的新消息发送给订阅者;设有下述七个功能模块:数据通信模块,是服务器端的最底层模块,负责接收所有来自客户端的数据,并传送给请求处理模块,同时将所有来自服务器端的数据发送到网络,再传送给客户端。请求处理模块,负责处理来自数据通信模块的所有数据,包括客户端的发布请求、订阅请求及其对已消费消息的确认信号,并传送给相应模块:若是发布请求,则告知主题管理模块更新相关主题信息,再将该请求中的消息数据发送给消息存储模块;若是订阅请求,则告知订阅管理模块更新相关订阅者的信息;若是确认信号,则将该信号分别传递给消息传递模块和订阅管理模块。主题管理模块,负责管理系统中所有主题的相关信息:包括系统拥有的主题数量、每个主题的存储位置、当前消息数量及其当前的订阅者信息。订阅管理模块,负责管理系统中所有主题订阅者的相关信息:包括订阅者已订阅的主题信息,以及每个订阅者对其各自已订阅主题的消费信息。消息存储模块,负责在接收到来自请求处理模块的消息后,将每个主题新发布消息先送到消息缓存区进行缓存,然后根据情况酌情送到消息持久层单元,以便进行持久化存储到数据库或作其他处理。消息传递模块,负责将主题消息传递给对应的订阅者:先从订阅管理模块和主题管理模块获取订阅者信息及其所订阅的主题信息后,确定要给每个订阅者传递的各自不同消息后,再从消息存储模块拿取需要传递的消息,最后经由数据通信模块将消息发送给用户。因为基于主题的发布/订阅系统是将消息归类为不同的主题,并以主题为单位进行发布和订阅,而消息队列模型则是将消息归类为不同的队列,并以队列为单位进行生产和消费。由此可见,主题发布/订阅模型中的“主题”和消息队列模型中的“队列”相类似,都是作为消息的归类单位。而且,两种模型的消息生产过程几乎没有差异,但其消息的消费过程差异很大,这是由模型本身的不同语义决定的。在发布/订阅模型中,一条消息可以被多次消费,而消息队列模型中一条消息只能被消费一次。由于主题发布/订阅模型和消息队列模型有很多相似之处,所以在主题发布/订阅模型系统中添加消息队列模型语义时,可以大量复用原有发布/订阅模型来实现之,这样做既降低了开发难度,还使得新添加的队列模型可以与原有发布/订阅模型更好地结合。另外,为了降低对原有发布/订阅模型的影响,添加消息队列模型时,应尽量不更改原有发布/订阅系统的核心操作流程。所以本发明采用复用原有的发布/订阅系统的服务端,只更改原有客户端的结构组成及其实现方式来添加消息队列模型。诚然,为了能够在现有的发布/订阅系统中增添消息队列模型,使得该系统能够同时支持两种消息传递模型,业内科技人员作了大量的研发工作,解决了许多难题。

技术实现要素:
有鉴于此,本发明的目的是提供一种增加消息队列模型的发布/订阅系统及其工作方法,本发明宗旨是解决用户变换底层消息传递模型比较困难的问题,例如:从发布/订阅模型转换为消息队列模型,或从消息队列模型转换为发布/订阅模型,亦或是同时需要两种消息传递模型。本发明系统是在基于主题的发布/订阅系统上增加消息队列模型的语义,使得原本只支持单一发布/订阅模型的消息中间件,能够同时支持发布/订阅和消息队列两种模型,同时保证两种模型的可用性、伸缩性和其他性能都在可接受范围内,使得用户在使用消息中间件时,既可随时从单一消息传递模型转换为同时使用两种模型,也可随时从使用其中一种模型转换为使用另一种模型,从而满足用户变换消息传递模型的需求。为了达到上述目的,本发明提供了一种增加消息队列模型的发布/订阅系统,包括由多个服务节点组成的分布式消息中间件服务端集群和由众多终端组成的客户端集群,所述分布式消息中间件服务端集群中的服务节点仍然由原发布/订阅系统的相应模块所组成,且各模块功能与信息传递关系保持不变;其特征在于:所述系统还增设有分布式协调服务器集群,由该分布式协调服务器集群提供的分布式协调服务对该系统中的客户端集群进行协调管理;且该系统是在基于主题的发布/订阅系统中增添消息队列模型而构成的,其中的客户端同时设有发布/订阅模型和消息队列模型的两种调用接口,以供用户在使用消息中间件时,能够不更换底层消息中间件就调用两种不同接口,直接选择使用发布/订阅或消息队列两种不同的消息传递模型;故该系统客户端既是发布/订阅模型中消息的发布者和订阅者:负责向服务端中设定主题发送消息和接收来自服务端中已订阅主题的新消息;又是消息队列模型中队列消息的生产者和消费者:负责向服务端中设定队列发送消息和接收来自服务端中已绑定队列的新消息;该客户端设有下述六个功能模块:数据通信模块,作为客户端的最底层模块,负责接收所有来自服务端的处理响应或消息数据,并传送给响应处理模块;同时将所有来自客户端的请求或消息数据发送至网络,以供传送给服务端;响应处理模块,负责处理来自数据通信模块的、包括服务端对客户端发布请求和订阅请求的处理响应,以及服务端发送给订阅者或消费者的主题或队列消息,并传送给相应模块:若是请求的处理响应,则传送给发布/订阅接口模块;若是主题或队列的消息,则传送给消息处理模块;发布/订阅接口模块,用作用户发布消息和订阅主题的交互接口,将发布请求和订阅请求经由数据通信模块传送到服务端;设有消息发布者和消息订阅者两个接口单元:消息发布者接口单元用于将消息发布到设定主题,并生成发布请求,消息订阅者接口单元用于订阅用户感兴趣的主题消息,并生成订阅请求;消息队列接口模块,用作用户发送和接收队列消息的交互接口,将发送请求和接收请求经由发布/订阅接口模块传递到数据通信模块,再传送到服务端;设有队列生产者和队列消费者两个接口单元:队列生产者接口单元用于发送消息到设定队列,并生成发送请求和调用发布/订阅接口模块的发布者单元,将发送请求封装成发布请求后,传递给数据通信模块;队列消费者接口单元负责绑定用户要求消费的队列,并生成接收请求和调用发布/订阅接口模块的订阅者单元,将接收请求封装成订阅请求传递给数据通信模块;协调服务模块,设有锁管理单元和队列指针单元,其中的锁管理单元负责为用户绑定的每个队列维护其队列锁,队列指针单元负责为用户绑定的每个队列维护其队列指针;且该队列锁和队列指针将根据消息处理模块的消息消费单元传递来的信息进行及时更新;消息处理模块,负责接收与消费来自服务端的主题或队列的消息,并对已消费消息向服务端返回确认信号;设有三个功能单元:消息缓存单元负责将响应处理模块发送来的主题或队列消息进行缓存,直到该消息被消费时被取出;消息确认单元负责对已消费的主题或队列消息向服务端返回确认信号;消息消费单元负责消息的消费管理:在发布/订阅模型中,用户消费时从消息缓存单元直接提取主题消息;而在消息队列模型中,用户消费每条消息时,需要先从协调服务模块的锁管理单元获取队列锁,再从队列指针单元获取队列指针后,才能从消息缓存单元中提取该条队列消息;且在每条队列消息被消费结束后,负责将队列锁释放给锁管理单元和更新队列指针单元中的队列指针。所述分布式消息中间件服务端集群,作为该系统的控制中心,既负责接收发布/订阅模型中的消息发布者发送来的消息,并将该消息存储到对应的主题,以及将已订阅主题的新消息发送给消息订阅者;也负责接收消息队列模型中的消息生产者发送来的消息,并将该消息存储于设定队列,以及将已绑定队列的新消息发送给消息消费者;设有下述六个功能模块:数据通信模块,作为服务端的最底层模块,负责接收所有来自客户端的数据,并传送给请求处理模块,同时将所有来自其他模块的数据发送到网络,再传送给客户端;请求处理模块,负责处理来自数据通信模块的所有数据,包括客户端的发布请求、订阅请求及其对已消费消息的确认信号,并传送给相应模块:若是消息发布请求,则告知主题管理模块更新相关主题信息,再将该请求中的消息数据发送给消息存储模块;若是订阅请求,则告知订阅管理模块更新相关订阅者的信息;若是确认信号,则将该信号分别传递给消息传递模块和订阅管理模块;主题管理模块,负责管理系统中所有主题的相关信息:包括系统拥有的主题数量、每个主题的存储位置、当前消息数量及其当前的订阅者信息;订阅管理模块,负责管理系统中所有主题订阅者的相关信息:包括订阅者已订阅的主题信息,以及每个主题订阅者对各自已订阅主题的消费信息;消息存储模块,负责在接收到来自请求处理模块的消息后,将每个主题新发布消息先送到消息缓存区进行缓存,同时将该新发布消息送到消息持久层单元进行持久化存储;消息传递模块,负责将主题消息传递给对应的订阅者:先从订阅管理模块和主题管理模块获取订阅者信息及其所订阅的主题信息后,再从消息存储模块拿取需要传递的主题消息,最后经由数据通信模块将该主题消息发送给客户端。所述由多个服务节点组成的分布式消息中间件服务端集群、分布式协调服务器集群和由众多终端组成的客户端集群共三个集群内都包括数量不等的多个节点,且这三个集群共同部署在相同节点上,或分别部署在不同节点上。所述分布式协调服务器集群采用包括ApacheZooKeeper系统的分布式协调服务器构成,其提供的分布式协调服务负责维护每个队列的全局消费指针:即队列指针及其队列锁;每个队列的所有消费者在从本地缓存提取每条队列消息进行消费前,必须先从分布式协调服务中获取该队列锁;若未获取到该队列锁,则等待;若获取到该队列锁,则读取分布式协调服务中队列的全局消费指针,获悉下一条应该被消费的消息序号后,才能够从本地缓存中提取对应序号的队列消息,然后更新全局消费队列指针:将其数值加1;最后释放该队列锁,即将该队列锁返回给分布式协调服务,以供其他消费者使用。所述消息队列是计算机科学中的一种进程间通信或同一进程的不同线程之间的通信方式,消息队列模型使用异步通信协议,以使通信参与者在空间和时间上解耦:队列消息的生产者和消费者无需直接通信,队列消息被发送到一个队列进行保存,直到消费者从该队列中读取该消息;且在消息队列模型中,每条消息只能够被一个消费者消费、即读取和使用之,也就是每条消息只能够被消费一次。为了达到上述目的,本发明还提供了一种采用本发明增加消息队列模型的发布/订阅系统的工作方法,其特征在于:所述工作方法分别包括消息队列模型中的队列消息生产和消费过程,以及发布/订阅模型中的主题消息发布和订阅过程;且因消息队列模型中的队列消息生产过程和发布/订阅模型中的主题消息发布过程的操作步骤相同,故消息队列模型中的队列生产者发送队列消息的操作就复用了发布/订阅模型中的主题消息发布过程:将该系统中向某个队列发送消息直接视为向某个主题发布消息,每条消息是按照时间顺序逐条发送到指定队列;消息队列模型的队列消息生产过程包括下述操作步骤:步骤1,客户端的队列生产者发出发送消息请求:客户端的消息队列接口模块中的队列生产者单元发起消息发送过程,将要发送的队列消息传递给发布/订阅接口模块的消息发布者单元,消息发布者单元将该发送请求封装成发布请求后,经由数据通信模块发送至网络,再传送至系统服务端;步骤2,服务端接收和处理客户端的发布请求并返回响应:服务端的数据通信模块接收到发布请求后,直接将其传递给请求处理模块;请求处理模块成功解析发布请求后,先通过数据通信模块向客户端返回发布成功响应,告诉客户端已成功接收该队列消息;同时通知主题管理模块更新该队列消息所属队列的相关信息,并将发布请求中的消息数据传递给存储管理模块进行存储;步骤3,服务端对新队列消息进行存储:存储管理模块接收到该队列消息后,先将该队列消息传递至消息缓存区单元进行缓存,同时将其传递至消息持久化层单元,以便将该队列消息持久化存储于数据库中;步骤4,客户端接收和处理返回的响应:客户端的数据通信模块接收到服务端发来的发布成功响应后,直接上传给响应处理模块;响应处理模块成功解析后,通知发布/订阅接口模块的消息发布者单元发布成功。因为根据消息队列的语义,队列消费者在接收消息时,需先发出与要消费的队列相连接的接收请求,以便将队列消费者和该要消费的队列消息进行一一绑定;而所述系统中的消息队列模型是基于发布/订阅系统实现的,队列是用主题模拟的,故绑定队列消费者及其消费队列的实质是绑定消息订阅者和主题,并采用订阅操作实现之;因此,所述系统的消息队列模型中,队列消费者在发出接收请求时,实际上是执行绑定队列消费者及其消费的队列消息的订阅操作。所述消息队列模型中队列消息的消费过程包括下述操作步骤:步骤A,客户端的队列消息消费者发出接收消息请求:客户端的消息队列接口模块中的队列消费者单元发出接收请求,将其传递给发布/订阅接口模块的消息订阅者单元,消息订阅者单元将该接收请求封装成一个订阅请求,经由数据通信模块发送至网络,再传送至系统服务端;步骤B,服务端接收和处理客户端的订阅请求并返回响应:服务端的数据通信模块接收到订阅请求后,直接传递给请求处理模块;请求处理模块成功解析订阅请求后,先从主题管理模块中获取消费队列、其实质为主题的相关信息,并通过数据通信模块向客户端返回订阅成功响应;再通知订阅管理模块更新相关订阅信息,以实现队列消费者与其消费队列的绑定;最后通知消息传递模块准备发送队列消息给队列消费者;步骤C,服务端开始发送消息过程:在发送队列消息前,消息传递模块先分别从主题管理模块和订阅管理模块获取消费队列和队列消费者的相关信息,并根据这些信息告知消息存储模块需要提取的队列消息;消息存储模块先从消息缓存区查找相关信息,如果没有找到,再去消息持久化层查找;并在成功找到后,将该队列消息返回给消息传递模块;由消息传递模块直接将该队列消息经由数据通信模块发送至网络,再传送至客户端;步骤D,客户端接收和处理来自服务端的消息:客户端的数据通信模块将接收到的订阅成功响应或队列消息直接传递给响应处理模块,响应处理模块若接收到订阅成功响应,则通知发布/订阅接口模块中的队列订阅者单元订阅成功;若接收到服务端发来的队列消息,则将该队列消息传递给消息处理模块;消息处理模块将该队列消息放入消息缓存单元,等到消费者消费队列消息时再取出;步骤E,队列消费者开始消费队列消息,并返回确认信号;步骤F,服务端接收并处理确认信号:服务端的数据通信模块接收到消息确认信号后,直接传递给请求处理模块;请求处理模块成功解析后,通知订阅管理模块更新相关信息,并将确认信号传递给消息发送模块告知哪些消息已被成功消费。所述步骤E包括下列操作内容:(E1)队列消费者消费每条队列消息时,先调用消息处理模块中的消息消费单元,让其从协调服务模块的锁管理单元尝试获取队列锁;若此时队列锁被其他消费者占有,则处于等待;直到成功获取到该队列锁后,执行步骤(E2);(E2)消息消费单元从协调服务模块的队列指针单元获取相应的队列指针,根据队列指针确定当前应该消费哪条队列消息后,再从消息缓存单元提取该条队列消息;(E3)消息消费单元每次从消息缓存单元提取完一条队列消息,就释放该队列锁、将其返回给锁管理单元,并更新队列指针单元中的队列指针值,同时向消息确认单元返回已消费队列消息的确认信号;(E4)消息确认单元通过数据通信模块向服务端返回已消费队列消息的确认信号,告知服务端哪条队列消息已被成功消费。本发明的创新技术是:在基于主题的发布/订阅中间件上增加消息队列模型,再利用分布式协调服务对多个消费者同时消费队列消息进行协调和同步的技术。利用队列锁来控制多个消费者之间同时企图消费队列消息的技术,还利用全局的队列消费指针来保证每条消息只被消费一次、且顺序被消费的技术。本发明的优点是:利用主题发布/订阅模型和消息队列模型的相似之处,在添加消息队列模型时最大程度地利用了原有主题发布/订阅系统的结构组成及其工作方法,从而大大减少了研发成本和硬件成本。另外,由于本发明系统中的消息队列模型传递方式大量复用了原有主题发布/订阅模型中的主题消息的传输方法,使得两种模型较好地实现彼此互相兼容,能够稳定、可靠地运行于同一个消息中间件系统中。总之,本发明利用较低的经济成本实现了一个同时支持发布/订阅和消息队列两种消息传递模型的系统,使得用户在使用消息中间件时,既可随时从单一消息传递模型转换为同时使用两种模型,也可随时从使用其中一种模型转换为使用另一种模型,较好地满足了用户变换底层消息传递模型的需求。附图说明图1是现有技术的基于主题的发布/订阅系统结构组成示意图。图2是本发明增加消息队列模型的发布/订阅系统物理架构示意图。图3是本发明增加消息队列模型的发布/订阅系统、即支持两种消息传递模型的系统结构组成示意图。图4是本发明系统在消息队列模型中消息发送时序图。图5是本发明系统在消息队列模型中消息消费时的客户端时序图。图6是本发明系统在消息队列模型中消息消费时的服务端时序图。图7是原Hedwig系统消息流向示意图。图8是本发明增加消息队列模型的发布/订阅系统的消息流向图。具体实施方式为使本发明的目的、技术方案和优点更加清楚,下面结合附图对本发明作进一步的详细描述。众所周知,现在使用的基于主题的发布/订阅系统中,消息被归类成不同的主题,并以主题为单位进行发布和订阅。发布者发布消息时需要指定发布到哪个主题,订阅者在消费前,也需要指定订阅哪个主题。所有发布到某个主题的消息会被所有订阅了这个主题的订阅者接收,即一条消息会被多个消费者消费。而在消息队列模型的中间件中,消息被归类成不同的队列,并以队列为单位进行生产和接收。生产者发送消息时需要指定发送到哪个队列,但消费者不需要先执行订阅步骤就能接收到队列中的消息。同时,队列中的某一条消息最终只会被一个消费者接收,即一条消息只会被一个消费者消费。本发明系统是在基于采用推模式和保证消息有序性的主题发布/订阅系统中添加消息队列模型实现的。在推模式的发布/订阅系统中,有新消息产生时,系统就会主动将新消息推送给订阅者。订阅者本地则是先缓存这些消息,然后等要消费时,再从缓存中提取消息。为保证消息有序性,消息会自动按照发布的先后顺序被订阅者消费,主题中的所有消息都会被严格按照先后顺序进行编号。这样订阅者缓存中的消息即使出现乱序,也可以根据消息编号被订阅者顺序地消费。为了复用原有的系统模型,本发明系统是把主题发布/订阅系统中的“主题”当做消息队列系统中的“队列”,这样就使得原发布/订阅系统中同一主题的所有订阅者就可以视为消息队列系统中同一队列的消费者集群。由于消息队列是计算机科学中的一种进程间通信或同一进程的不同线程之间的通信方式,消息队列模型使用异步通信协议,以使通信参与者在空间和时间上解耦:队列消息的生产者和消费者无需直接通信,队列消息被发送到一个队列进行保存,直到消费者从该队列中读取该消息。而且,在消息队列模型中,要求队列中的每一条消息只能够被一个消费者消费、即读取和使用之,也就是每一条消息只能够被消费一次。而原有发布/订阅模型中的每个主题的每条消息可能被消费多次,所以在现有系统中添加消息队列模型的关键技术时:将原有系统中某个主题的一条消息可能被多个订阅者消费,修改为只能被其中一个订阅者消费,即队列中的每一条消息只能够被消费者集群中的某一个消费者消费。再结合前述的推模式的主题发布/订阅系统特点可知:队列(即主题)中的所有消息在被消费以前,应缓存于消费者(即订阅者)一端。那么,只要保证每个消费者从本地缓存中提取队列消息消费时,只能拿取该系统中其他消费者还没有消费过的消息,就能够实现每条消息只被消费一次的消息队列模型语义。为了保证每个消费者只能够从缓存中拿取其他消费者没有消费过的消息,各个消费者之间首先需要协调,还要实现同步。协调是为了保证队列中消息按照顺序被各消费者拿取,并且不会被重复拿取。由于消费者集群中各消费者可以分布在网络中不同物理节点,在这种分布式环境中实现协调,需要借助于分布式协调服务器集群提供的分布式协调服务。分布式协调服务为每个消息队列都会维护一个全局消费队列指针,这个全局消费队列指针可以向队列中的所有消费者提供读或写的操作。消费队列指针用来指向队列未被消费过的消息中最早产生的那条消息,由于原有的主题发布订阅/系统中已对队列消息按照其生产的先后顺序进行了由小到大的编号,所以全局消费队列指针会指向队列中未被消费过的消息中序号最小的消息。同步是为了保证任意时刻都只有一个消费者从缓存中拿取消息,防止多个消费者同时拿取同一条消息。消费者之间的同步的实质是一个串行访问资源、即缓存的问题,最简单的实现方式就是使用锁。每个消息队列对应一把锁,该队列的所有消费者共享这把锁;但在任意时刻,该锁最多只能被一个消费者持有。每个消费者在消费队列中的某条消息前,必须先获得该队列的锁,待到完成该消息的消费后,再将锁释放,以供其他消费者进行后续消费。简单来说,就是谁持有队列的锁,谁就能消费队列中的消息,即从自己本地缓存中拿取消息。由于每一个队列只有一把锁,且该锁最多能被一个消费者持有,所以任意时刻都不会发生多个消费者同时从缓存中拿取同一条消息的情况。总之,本发明系统的核心技术是在原主题发布/订阅系统的客户端上增加消息队列模型,使得客户端同时具备发布/订阅和消息队列的两种调用接口。这样用户在使用该消息中间件时,就能够通过调用不同接口来选择使用不同的模型,在不更换底层消息中间件的情况下,就能实现消息传递模型的转换。由于消息队列模型与发布/订阅模型有很多共同之处,两者客户端的结构组成也有相似之处:在两种模型中,客户端都扮演着两个角色:发布/订阅模型中客户端是发布者、也是订阅者,消息队列模型中客户端是生产者、也是消费者。所以本发明系统中的消息队列的客户端组成构造将会大量复用原发布/订阅模型的客户端的组成结构。考虑到“主题”和“队列”的相似性,在本发明系统中,以原主题发布/订阅系统中的“主题”来模拟消息队列中的“队列”。创建一个主题将直接被视为创建一个队列,向一个主题发布消息将直接被视为向队列生产消息,因为这两个阶段在两种模型的客户端的操作步骤基本相同。但是,由于两种模型中消费消息的操作流程是不同的,所以实现消息队列模型的关键是将原系统中的订阅和消费操作包装为消息队列中的消息消费操作。在消息队列模型中,消费者在消费消息前,需要向服务器发出队列接收请求,以绑定消费队列。本发明是利用该步骤同时完成对队列(即原主题)的订阅操作,以此实现消费者与消费队列的绑定。这样消费者与队列完成绑定后,队列中的消息就会开始从服务端发送到客户端,并在客户端进行缓存和等待被消费者消费。由前面介绍可知,在实现消息队列模型时,本发明系统需要借助分布式协调服务来维护队列全局消费指针(即队列指针)和锁(即队列锁),所以该系统结构组成需要增加一个分布式协调服务器集群(参见图2所示)。所以,本发明系统的整体架构包括3大部分:系统服务端集群和系统客户端集群,以及分布式协调服务器集群。这三个集群内部有多个节点组成,节点数量根据具体需要可随机自行改变。该三个集群可以共同部署在相同的节点上,也可以各自部署在不同的节点上。其中,分布式协调服务器集群直接使用已有的分布式协调服务,例如目前技术比较成熟的ApacheZooKeeper系统提供的分布式协调服务。其提供的分布式协调服务负责维护每个队列的全局消费指针、即队列指针及其队列锁:每个队列的所有消费者在从本地缓存提取每条队列消息进行消费前,必须先从分布式协调服务中获取该队列锁;若未获取到该队列锁,则等待;若成功获取到该队列锁,则读取分布式协调服务中队列的全局消费指针,获悉下一条应该被消费的消息序号后,才能够从本地缓存中提取对应序号的队列消息,然后更新全局消费队列指针:将其数值加1;最后释放该队列锁,即将该队列锁返回给分布式协调服务,以供其他消费者使用。参见图3,介绍本发明能够同时支持发布/订阅模型和消息队列模型的系统结构组成:对比图1中只支持单模型的发布/订阅系统结构组成图可以发现,在增加消息队列模型后,其中的分布式消息中间件服务端集群中的服务节点仍然由原发布/订阅系统的相应模块所组成,且各模块功能与信息传递关系保持不变;也就是服务端和原来一样,未做改动。但是,客户端因同时设有发布/订阅模型和消息队列模型的两种调用接口,以供用户在使用消息中间件时,能够不更换底层消息中间件就调用两种不同接口,直接选择使用发布/订阅或消息队列两种不同的消息传递模型。故该客户端既是发布/订阅模型中消息的发布者和订阅者:负责向服务端中设定主题发送消息和接收来自服务端中已订阅主题的新消息;又是消息队列模型中队列消息的生产者和消费者:负责向服务端中设定队列发送消息和接收来自服务端中已绑定队列的新消息。其结构变动比较大。下面先介绍该客户端设置的下述六个模块功能:数据通信模块:作为客户端的最底层模块,负责接收所有来自服务端的处理响应或消息数据,并传送给响应处理模块;同时将所有来自客户端的请求或消息数据发送至网络,以供传送给服务端。响应处理模块:负责处理来自数据通信模块的、包括服务端对客户端发布请求和订阅请求的处理响应、即处理成功或失败,以及服务端发送给订阅者或消费者的主题或队列消息,并传送给相应模块:若是请求的处理响应,则传送给发布/订阅接口模块;若是主题或队列的消息,则传送给消息处理模块。发布/订阅接口模块:用作用户发布消息和订阅主题的交互接口,将发布请求和订阅请求经由数据通信模块传送到服务端;设有消息发布者和消息订阅者两个接口单元:消息发布者接口单元用于将消息发布到设定主题,并生成发布请求,消息订阅者接口单元用于订阅用户感兴趣的主题消息,并生成订阅请求。消息队列接口模块:用作用户发送和接收队列消息的交互接口,将发送请求和接收请求经由发布/订阅接口模块传递到数据通信模块,再传送到服务端;设有队列生产者和队列消费者两个接口单元:队列生产者接口单元用于发送消息到设定队列,并生成发送请求和调用发布/订阅接口模块的发布者单元,将发送请求封装成发布请求后,传递给数据通信模块;队列消费者接口单元负责绑定用户要求消费的队列,并生成接收请求和调用发布/订阅接口模块的订阅者单元,将接收请求封装成订阅请求传递给数据通信模块。协调服务模块:设有锁管理单元和队列指针单元,其中的锁管理单元负责为用户绑定的每个队列维护其队列锁,队列指针单元负责为用户绑定的每个队列维护其队列指针;且该队列锁和队列指针将根据消息处理模块的消息消费单元传递来的信息进行及时更新。消息处理模块:负责接收与消费来自服务端的主题或队列的消息,并对已消费消息向服务端返回确认信号;设有三个功能单元:消息缓存单元负责将响应处理模块发送来的主题或队列消息进行缓存,直到该消息被消费时被取出;消息确认单元负责对已消费的主题或队列消息向服务端返回确认信号;消息消费单元负责消息的消费管理:在发布/订阅模型中,用户消费时从消息缓存单元直接提取主题消息;而在消息队列模型中,用户消费每条消息时,需要先从协调服务模块的锁管理单元获取队列锁,再从队列指针单元获取队列指针后,才能从消息缓存单元中提取该条队列消息;且在每条队列消息被消费结束后,负责将队列锁释放给锁管理单元和更新队列指针单元中的队列指针。再介绍本发明系统中的控制中心:分布式消息中间件服务端集群,既负责接收发布/订阅模型中的消息发布者发送来的消息,并将该消息存储到对应的主题,以及将已订阅主题的新消息发送给消息订阅者;也负责接收消息队列模型中的消息生产者发送来的消息,并将该消息存储于设定队列,以及将已绑定队列的新消息发送给消息消费者。设有下述七个功能模块:数据通信模块:作为服务端的最底层模块,负责接收所有来自客户端的数据,并传送给请求处理模块,同时将所有来自其他模块的数据发送到网络,再传送给客户端。请求处理模块:负责处理来自数据通信模块的所有数据,包括客户端的发布请求、订阅请求及其对已消费消息的确认信号,并传送给相应模块:若是消息发布请求,则告知主题管理模块更新相关主题信息,再将该请求中的消息数据发送给消息存储模块;若是订阅请求,则告知订阅管理模块更新相关订阅者的信息;若是确认信号,则将该信号分别传递给消息传递模块和订阅管理模块。主题管理模块,负责管理系统中所有主题的相关信息:包括系统拥有的主题数量、每个主题的存储位置、当前消息数量及其当前的订阅者信息。订阅管理模块,负责管理系统中所有主题订阅者的相关信息:包括订阅者已订阅的主题信息,以及每个主题订阅者对各自已订阅主题的消费信息。消息存储模块,负责在接收到来自请求处理模块的消息后,将每个主题新发布消息先送到消息缓存区进行缓存,同时将该新发布消息送到消息持久层单元进行持久化存储。消息传递模块,负责将主题消息传递给对应的订阅者:先从订阅管理模块和主题管理模块获取订阅者信息及其所订阅的主题信息后,再从消息存储模块拿取需要传递的主题消息,最后经由数据通信模块将该主题消息发送给客户端。下面介绍本发明增加消息队列模型的发布/订阅系统的工作方法:分别包括消息队列模型中的队列消息生产和消费过程,以及发布/订阅模型中的主题消息发布和订阅过程。但是,因消息队列模型中的队列消息生产过程和发布/订阅模型中的主题消息发布过程的操作步骤相同,故消息队列模型中的队列生产者发送队列消息的操作就复用了发布/订阅模型中的主题消息发布过程:将该系统中向某个队列发送消息直接视为向某个主题发布消息,每条消息是按照时间顺序逐条发送到指定队列。参见图4,介绍本发明系统在消息队列模型的队列消息生产过程的操作步骤:步骤1,客户端的队列生产者发出发送消息请求:客户端的消息队列接口模块中的队列生产者单元发起消息发送过程,将要发送的队列消息传递给发布/订阅接口模块的消息发布者单元;消息发布者单元将该发送请求封装成发布请求后,经由数据通信模块发送至网络,再传送至服务端。步骤2,服务端接收和处理客户端的发布请求并返回响应:服务端的数据通信模块接收到发布请求后,直接将其传递给请求处理模块;请求处理模块成功解析发布请求后,先通过数据通信模块向客户端返回发布成功响应,告诉客户端已成功接收该队列消息;同时通知主题管理模块更新该队列消息所属队列的相关信息,并将发布请求中的消息数据传递给存储管理模块进行存储。步骤3,服务端对新队列消息进行存储:存储管理模块接收到该队列消息后,先将该队列消息传递至消息缓存区单元进行缓存;同时将其传递至消息持久化层单元,以便将该队列消息持久化存储于数据库中。步骤4,客户端接收和处理返回的响应:客户端的数据通信模块接收到服务端发来的发布成功响应后,直接上传给响应处理模块;响应处理模块成功解析后,通知发布/订阅接口模块的消息发布者单元发布成功。因为根据消息队列的语义,队列消费者在接收消息时,需先发出与要消费的队列相连接的接收请求,以便将队列消费者和该要消费的队列消息进行一一绑定;而本发明系统中的消息队列模型是基于发布/订阅系统实现的,队列是用主题模拟的,故绑定队列消费者及其消费队列的实质是绑定消息订阅者和主题,并采用订阅操作实现之。因此,该系统的消息队列模型中,队列消费者在发出接收请求时,实际上是执行绑定队列消费者及其消费的队列消息的订阅操作。参见图5和图6,介绍本发明系统在消息消费过程中的操作步骤:步骤A,客户端的队列消息消费者发出接收消息请求:客户端的消息队列接口模块中的队列消费者单元发出接收请求,将其传递给发布/订阅接口模块的消息订阅者单元,消息订阅者单元将该接收请求封装成一个订阅请求,经由数据通信模块发送至网络,再传送至系统服务端。步骤B,服务端接收和处理客户端的订阅请求并返回响应:服务端的数据通信模块接收到订阅请求后,直接传递给请求处理模块;请求处理模块成功解析订阅请求后,先从主题管理模块中获取消费队列、其实质为主题的相关信息,并通过数据通信模块向客户端返回订阅成功响应;再通知订阅管理模块更新相关订阅信息,以实现队列消费者与其消费队列的绑定;最后通知消息传递模块准备发送队列消息给队列消费者。步骤C,服务端开始发送消息过程:在发送队列消息前,消息传递模块先分别从主题管理模块和订阅管理模块获取消费队列和队列消费者的相关信息,并根据这些信息告知消息存储模块需要提取的队列消息;消息存储模块先从消息缓存区查找相关信息,如果没有找到,再去消息持久化层查找;并在成功找到后,将该队列消息返回给消息传递模块;由消息传递模块直接将该队列消息经由数据通信模块发送至网络,再传送至客户端。步骤D,客户端接收和处理来自服务端的消息:客户端的数据通信模块将接收到的订阅成功响应或队列消息直接传递给响应处理模块,响应处理模块若接收到订阅成功响应,则通知发布/订阅接口模块中的队列订阅者单元订阅成功;若接收到服务端发来的队列消息,则将该队列消息传递给消息处理模块;消息处理模块将该队列消息放入消息缓存单元,等到消费者消费队列消息时再取出。步骤E,队列消费者开始消费队列消息,并返回确认信号。该步骤包括下列操作内容:(E1)队列消费者消费每条队列消息时,先调用消息处理模块中的消息消费单元,让其从协调服务模块的锁管理单元尝试获取队列锁;若此时队列锁被其他消费者占有,则处于等待;直到成功获取到该队列锁后,执行步骤(E2)。(E2)消息消费单元从协调服务模块的队列指针单元获取相应的队列指针,根据队列指针确定当前应该消费哪条队列消息后,再从消息缓存单元提取该条队列消息。(E3)消息消费单元每次从消息缓存单元提取完一条队列消息,就释放该队列锁、将其返回给锁管理单元,并更新队列指针单元中的队列指针值,同时向消息确认单元返回已消费队列消息的确认信号。(E4)消息确认单元通过数据通信模块向服务端返回已消费队列消息的确认信号,告知服务端哪条队列消息已被成功消费。步骤F,服务端接收并处理确认信号:服务端的数据通信模块接收到消息确认信号后,直接传递给请求处理模块;请求处理模块成功解析后,通知订阅管理模块更新相关信息,并将确认信号传递给消息发送模块告知哪些消息已被成功消费。步骤F,服务端接收并处理确认信号:服务端的数据通信模块接收到消息确认信号后,直接传递给请求处理模块;请求处理模块成功解析后,通知订阅管理模块更新相关信息,并将确认信号传递给消息发送模块告知哪些消息已被成功消费。本发明已经进行了多次仿真实施试验,也就是在实际使用的发布/订阅系统ApacheHedwig系统中,成功地添加了消息队列模型,使得该系统能够同时提供发布/订阅和消息队列两种消息传递模型。ApacheHedwig是开源的基于主题的发布/订阅系统,该系统的服务端由分布式服务器集群构成,并通过分布式协调服务ZooKeeper进行协调管理。该系统采用推模式来通知订阅者新消息的到达,通过给主题中消息进行顺序编号来保证消息有序性。参见图7,介绍只具有单一的发布/订阅模型的现有Hedwig系统架构,其系统消息流向如图7所示。每个主题可以有多个发布者和多个订阅者,主题位于系统服务端,发布者和订阅者位于系统客户端。当主题收到发布者新发布的消息时,系统服务端按照消息到达的先后顺序依次给每一条消息进行编号,序号越小,代表消息越早到达主题。由于Hedwig系统采用推模式,所以当系统服务端接收到新消息时,会实时将这些新消息主动推送给所有主题订阅者。订阅者收到推送过来的新消息后先在本地进行缓存,等到需要消费时再从缓存中拿取。根据前述内容可知,在增加消息队列模型时,需要借助分布式协调服务来协调和同步同一队列的多个消费者。由于Hedwig系统本身就具有分布式协调服务ZooKeeper,所以本发明实施例中消息队列模型需要的分布式协调服务是直接利用原Hedwig系统的ZooKeeper服务来实现的。因此,本发明系统实施例是在Hedwig系统上增加消息队列模型,原系统的发布/订阅模型不变,同时增加了消息队列模型后,此时的系统消息流向图如图8所示。在服务端处,队列与主题并存,分布式协调服务ZooKeeper同时为系统服务端集群和队列消费者集群提供服务,队列锁和全局消费队列指针则由ZooKeeper维护。由于本发明系统中的消息队列模型是用原系统的主题模拟队列实现,所以队列消息也和主题一样,可以有多个生产者和多个消费者,同时队列位于服务端,队列生产者和队列消费者位于客户端。当队列接收到生产者新生产的消息时,服务端按照消息到达的先后顺序依次给每一条消息进行编号:序号越小,代表消息越早到达队列。然后,服务端实时将这些新消息主动推送给该队列的所有消费者,消费者在接收到推送来的新消息后,先缓存于本地,等到需要消费时,再从ZooKeeper中获得锁和读取队列指针,顺序消费某一条消息。本发明的实施试验是成功的,实现了发明目的。
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1