一种基于数据行锁的异步消息队列算法的制作方法

文档序号:18009266发布日期:2019-06-25 23:47阅读:206来源:国知局

本发明涉及数据传输技术领域,尤其涉及一种基于数据行锁的异步消息队列算法。



背景技术:

通常,高性能和高可靠是互相违背的。高可靠意味着数据应该是持久化(磁盘存储)和事务支持的,并且同时应该支持非常便利,可靠的复制。而很多消息队列系统的实现,为了达到高性能,基本上都放弃了事务的支持,更进一步的,甚至放弃了持久化(磁盘存储)。这对交易系统等核心系统造成了巨大的负面影响,甚至导致了系统的不可用。



技术实现要素:

本发明的目的在于提供一种基于数据行锁的异步消息队列算法,实现了高性能的支持事务的队列。

为实现上述目的,本发明提供如下技术方案:

一种基于数据行锁的异步消息队列算法,其特征在于,包括创建消息队列、消息入列和消息出列;

所述创建消息队列的内容包括:为创建的消息队列指定一个唯一编码,再根据消息结构创建一个新的数据库表;

所述消息入列的内容包括:在创建的消息队列中插入一条消息,该消息包括所述唯一编码、消息的有效荷载,消息类型;

所述消息出列的内容包括:

s1,开始事务;

s2,执行出列,指定待出列的消息队列和最大出列数量;

s3,根据消息类型指定待出列消息,返回由待出列消息组成的第一结果集;

s4,迭代更新所述第一结果集中待出列消息发送状态,返回第二结果集;

s5,提交事务。

进一步的,所述消息结构包括以下六个数据:自增消息id,消息类型,发送标识,有效荷载,入列时间戳,出列时间戳;

所述自增消息id由数据库序列产生,确保唯一和并发当中的自增;

所述消息类型用于在消息出列的时候,进行特定类型的分拣;

所述发送标识为true/false的二元值,在消息入列的时候,该二元值是默认的false,执行出列时,更新二元值为true;

所述有效荷载以json数据为载体;

所述入列时间戳在消息入列的时候自动获取;

所述出列时间戳在消息出列的时候自动获取。

进一步的,所述s3和s4之间还包括以下步骤:

s31,若为并发情况,锁定所述待出列消息;

s32,限制锁定的数量,该数量的最大值不超过所述最大出列数量;

s33,根据锁定的结果更新所述第一结果集。

进一步的,所述创建消息队列的过程中,还记录唯一编码与数据库表的对应关系。

进一步的,所述待出列的消息队列通过所述唯一编码指定。

进一步的,所述最大出列数量通过出列函数指定。

与现有技术相比,本发明的有益效果是:本发明设计了独特的消息结构,由该消息结构创建的数据库表在物理上对不通用途的消息队列进行了物理隔离。一方面,本发明将消息的状态更新和出列作为一个事务进行处理,确保了消息发送的高可靠;另一方面,在消息出列的过程中,采用了批量处理,确保了消息发送的高性能。

具体实施方式

下面对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

postgresqldatabase是基于mvvc的关系型数据库实现。这个mvvc是指数据库在事务中通过多个数据版本对事务进行隔离,保障了事务的原子性,隔离性和一致性。我们的发明将利用这个特性,实现高性能的支持事务的队列服务。

数据库本身的性能是非常高的。在单机数据库实例当中,和普通的硬件配置,可以轻松的达到30k/s的数据插入速度。在批量处理当中这个速度可以更快。同时,持久性,一致性都得到了有效的保证。并且这个数据是非常便于检索和跟踪。

本实施例提供一种基于数据行锁的异步消息队列算法,具体步骤如下:

首先,本实施例设计了独特的消息结构,具体包括以下六个数据:自增消息id,消息类型,发送标识,有效荷载,入列时间戳,出列时间戳;

所述自增消息id[msgid]由数据库序列产生,确保逻辑唯一和并发当中的自增;

所述消息类型[typeid],使得我们的单个消息队列可以对多种类型服务进行消息分拣,这个消息类型[typeid]是由入列的应用指定。当数据出列的时候,我们进行特定的类型进行分拣,也可以对任意类型的消息执行出列动作,这取决于应用环境的需要;

所述发送标识为true/false的二元值(boolean型),说明这个消息是否已经被发送。本实施例用mvvc这个特性确保这个消息被并且只被发送一次。在消息入列的时候,该二元值是默认的false,执行出列时,更新二元值为true;

所述有效荷载以json数据为载体;本实施例将任意的数据,打包成json数据作为消息内容进行存储;

所述入列时间戳在消息入列的时候自动获取系统时间,表示了消息入列的时间;

所述出列时间戳在消息出列的时候自动获取系统消息,表示了消息出列,也就是发送消息的时间。

本实施例以上述消息结构为模板,在消息队列创建的时候,建立真正存储消息队列的数据库表。这样做的目的是在物理上,对不同用途的队列进行物理隔离。

从信息技术的角度来看,以消息的状态更新和出列作为一个事务进行处理,从而确保了消息发送的可靠性。具体的,本实施例具体包括了创建消息队列、消息入列和消息出列三部分。

所述创建消息队列的内容包括:为创建的消息队列指定一个唯一编码,再根据消息结构创建一个新的数据库表,这个数据库表被命名为mq_queue_[code];同时,在创建消息队列的过程中,还记录唯一编码与数据库表的一一对应关系。相应的,本实施例删除该消息队列的方法很简单,直接删除这个数据库表和对应关系的数据便可。

所述消息入列的内容包括:在创建的消息队列中插入一条消息,该消息包括消息队列的唯一编码、消息的有效荷载,消息类型;消息队列的唯一编码指定了该消息将要入列哪个消息队列,有效荷载存储的消息的具体内容,消息类型有利于后期的消息分拣。

所述消息出列的内容包括:

s1,开始事务;

s2,执行出列,指定待出列的消息队列、消息队列中的消息类型和最大出列数量。所述待出列的消息队列通过所述唯一编码指定。所述最大出列数量通过出列函数指定,默认值是1,其代表了一次出列动作,从消息队列中取出1个消息;当这个最大出列数量大于1时,则至多取出指定最大出列数量的消息,也有可能小于这个数量,因为消息队列中未必有足够多的消息。

s3,根据消息类型指定待出列消息,返回由待出列消息组成的第一结果集。具体的,出列函数通过消息类型[typeid]当中指定了所关心的待出列消息,只有入列的消息的消息类型匹配了这和出列指定的消息类型,才会匹配进行出列操作。当不指定消息类型时,意味着这个消息队列中的所有未出列消息都符合这个匹配。返回的第一结果集就是下面步骤进一步操作的数据对象。

s31,若为并发情况,锁定所述待出列消息并跳过已经被锁住的消息。这个通过forupdate语句实现,这样就支持了并发情况当中队列出列的唯一性。若不是并发情况,则直接执行s4。

s32,限制锁定的数量,该数量的最大值不超过所述最大出列数量;这保障了单个和批量两种情况的消息出列,在批量处理的时候,保障了算法的高性能。

s33,根据锁定的结果更新所述第一结果集作为下面步骤进一步操作的数据对象。

s4,迭代更新所述第一结果集中待出列消息发送状态,将对应消息的发送标识从默认的false更新为true,表示已经出列。同时标记出列的时间记录在出列时间戳内。迭代完成后,返回第二结果集;

s5,提交事务。

上述方法可用非常简洁的代码便可实现高可用、高性能、支持事务、支持批量的异步消息队列。这个消息队列可以替代目前市场上可获得的各种opensource以及商用的mq产品。普遍的,这些产品小则几十m,多则数百m的大小,部署,监测,可靠性,易用性方面,这个算法都有优势。在各类产品中大规模应用当中,从未遇到消息丢失等各种可靠性带来的问题。

对于本领域技术人员而言,显然本发明不限于上述示范性实施例的细节,而且在不背离本发明的精神或基本特征的情况下,能够以其他的具体形式实现本发明。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本发明的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化囊括在本发明内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1