分布式高并发消息队列推送系统的制作方法

文档序号:16067585发布日期:2018-11-24 12:49阅读:736来源:国知局

本发明涉及消息队列技术领域,尤其涉及一种分布式高并发消息队列推送系统。

背景技术

消息队列(messagequeue),是分布式系统中重要的组件,其通用的使用场景可以简单地描述为:当不需要立即获得结果,但是并发量又需要进行控制的时候,就是需要使用消息队列的时候。消息队列主要解决了应用耦合、异步处理、流量削锋等问题。

消息队列在实际应用中包括如下四个场景:1、应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;2、异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;3、限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;4、消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理。

现有的消息队列推送系统通常按通道来保证时序,但按通道保证时序的设定使得消费时并发力度受限,只能通过拆分消息存储通道来提高并发,这种方案成本较高,灵活性不够,且最大并发能力仍受限。



技术实现要素:

有鉴于此,本发明实施例提供一种分布式高并发消息队列推送系统,其成本低,灵活性高,能够实现队列消息的高并发推送。

一种分布式高并发消息队列推送系统,包括代理服务器、kafka消息存储系统和消息推送服务器集群,其中:

所述代理服务器,用于接收业务方的消息,所述消息中包含有关联业务标识位,所述代理服务器收到消息后根据消息中的关联业务标识位将消息存储至所述kafka消息存储系统的对应分区;

所述kafka消息存储系统,采用集群式布署来分布式存储分区;

所述消息推送服务器集群中的每个推送服务器包括一个或多个推送进程,推送进程用于处理对应分区中的消息,每个推送进程按所述kafka消息存储系统中消费者组名进行归组;

每个推送进程包括一个分区消费者线程,每个分区消费者线程配置多个消息推送子线程和一个分区消费位置管理器;

所述分区消费者线程用于消费所述kafka消息存储系统的分区中的消息,当分区消费者线程从对应分区顺序拉到消息后,依次轮询消息推送子线程,当遇到空闲消息推送子线程时,则将消息分配给该消息推送子线程,并记录该消息推送子线程与该消息的关联业务标识位的对应关系,并将消息的序号添加到分区消费位置管理器;后续若拿到相同关联业务标识位的消息,则分配给对应的消息推送子线程;

所述消息推送子线程用于在收到消息后将消息放入私有队列中,并顺序消费私有队列中的消息;

所述分区消费位置管理器用于维护当前分区消费者线程处理的消息的消费位置状态。

进一步的,同组中的推送进程拉取不同分区消息,不同组的推送进程可重复拉取同一分区消息。

进一步的,所述代理服务器采用集群式布署,所述代理服务器启动后与所述kafka消息存储系统建立长连,并提供网页服务器服务供业务方调用。

进一步的,所述代理服务器根据消息中的关联业务标识位将消息存储至所述kafka消息存储系统的对应分区包括:

所述代理服务器将消息中的关联业务标识位对所述kafka消息存储系统的分区数进行取余操作,将消息存储至余数对应的分区。

进一步的,每个推送服务器启动时初始化i*j个推送进程,其中i为所述kafka消息存储系统中分区数,j为所述kafka消息存储系统中消费者组名数量。

进一步的,所述消息推送子线程顺序消费私有队列中的消息,包括:

消息推送子线程推送业务采用轮循下游业务集群的方式,当推送失败或成功即将消费位置状态发送给分区消费位置管理器。

进一步的,所述分布式高并发消息队列推送系统还包括消费位置推送失败记录区。

进一步的,所述消费位置推送失败记录区的目录规则为组名/分区/消费位置;

若重启服务或者消息推送服务器集群中添加了新的推送进程导致重新分配kafka消息存储系统分区,则根据分配到的分区号及组名去对应的消费位置推送失败记录区加载失败的消息进行推送。

进一步的,每个推送服务器还包括用于监控其上每个推送进程中分区消费者线程状态的网页服务器。

进一步的,当分区消费位置管理器接收到推送成功或失败的消费位置状态时,扫描队列,取推送成功和推送失败相连续的最大位置提交到所述kafka消息存储系统,以使得下次从kafka消息存储系统拉取消息时从该位置拉取。

本发明实施例的分布式高并发消息队列推送系统,在原通道的基础上,重新定义时序粒度,对单个通道进行细致化拆分,提供了更大层度的并发推送方案。本实施例无需通过拆分消息存储通道来提高并发,只需调高消息推送子线程数或者增加推送进程即可提高并发,成本低,灵活性高,能够在保证业务时序要求的同时实现队列消息的高并发推送。

附图说明

为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。

图1为本发明的分布式高并发消息队列推送系统的结构原理图。

具体实施方式

下面结合附图对本发明实施例进行详细描述。

应当明确,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其它实施例,都属于本发明保护的范围。

本发明主要内容是实现一种基于关联业务问的消息队列推送系统。这是一个将互相依赖的业务通过消息推送相结合的系统。它应用消息分布式存储服务、分布式部署、消息推送技术、计算机协程、网络等技术,在保证业务时序要求的同时实现队列消息的高并发推送。

如图1所示,本发明实施例提供一种分布式高并发消息队列推送系统1,包括代理服务器(proxy)11、kafka消息存储系统12和消息推送服务器集群13,其中:

消息生产:

代理服务器11用于接收业务方的消息,所述消息中包含有关联业务标识位(associatedbusinessidentifier,abid),代理服务器11接收到业务方的消息后,根据消息中的abid将消息存储至kafka消息存储系统12的对应分区(即图中的part1、part2...partn),从而保证相同abid的消息按时序进入到同一分区;

具体的,abid可以利用消息中可使用的自定义字段,也可以直接使用目前kafka中消息的key字段;优选的,代理服务器11可以将消息中的abid对kafka消息存储系统12的分区数进行取余操作,将消息存储至余数对应的分区;

消息存储:

kafka消息存储系统12,采用集群式布署来分布式存储分区;

消息推送:

消息推送服务器集群13中的每个推送服务器(即图中的推送服务器1、推送服务器2,由于空间有限,图中仅示出了两个推送服务器,可以理解的是消息推送服务器集群可以包括更多个推送服务器)包括一个或多个推送进程(pushprocess,简称pp,即图中的pp1、pp2...ppn),推送进程用于处理对应分区中的消息,每个推送进程按kafka消息存储系统12中消费者组名进行归组(group),图1中,归组后即得多个消费组,分别为group1…groupn;

每个推送进程包括一个分区消费者线程(例如图中的partlconsumer),每个分区消费者线程配置多个消息推送子线程(即图中的win1、win2...winn,其中win为window的简称)和一个分区消费位置管理器(即图中的offsetmanager);

本发明实施例中,推送进程与分区具有对应关系,一个推送进程对应处理一个分区中的消息,该对应关系既可以是预先设定的,也可以由推送进程争抢分区确定而来;同时,由于一个推送进程包括一个分区消费者线程,故分区消费者线程与分区也有对应关系,一个分区消费者线程对应处理一个分区中的消息。

所述分区消费者线程用于消费所述kafka消息存储系统的分区中的消息,当分区消费者线程从对应分区顺序拉到消息后,例如可以通过dispatch(消息分配)模块依次轮询其对应的多个消息推送子线程,当遇到空闲的消息推送子线程时,则将消息分配给该空闲的消息推送子线程,并记录该消息推送子线程与该消息的abid的对应关系,并将消息的序号添加到分区消费位置管理器;后续若拿到相同abid的消息,则分配给对应的消息推送子线程,从而保证了关联消息的时序;

所述消息推送子线程用于在收到消息后将消息放入私有队列中,并顺序消费私有队列中的消息(即推送消息),具体的,消息推送子线程推送业务可以采用轮循下游业务集群的方式,从而均衡下游压力以及部分机器故障时仍可轮询到可用机器,当推送失败或成功即将消费位置offset状态发送给分区消费位置管理器;若推送服务器设置了无限重试模式,推送失败则会进入重试,直到推送成功。

所述分区消费位置管理器用于维护当前分区消费者线程处理的消息的消费位置offset状态(共三种状态:待推送、推送成功、推送失败),由于kafka消息存储系统的单个分区拆成了多个消息推送子线程来消费,若由消息推送子线程提交各自的消费位置到kafka,重启可能导致消息丢失,于是通过分区消费位置管理器对应每个分区消费者线程来统一管理分区的消费位置。

本发明实施例中,归组/分组的意义在于多个业务间可能需要重复消费同一条消息,如结算系统和库存系统需要消费同一条创建订单消息。每一个业务对应一个组,这个组即是kafka里的消费者组名。在一个具体的例子中,消费者组名可以包括结算业务组、库存业务组、商户后台业务组和物流调度业务组。

为适应业务场景的需要,优选的,同组中的推送进程拉取不同分区消息,不同组的推送进程可重复拉取同一分区消息。参见图1,group1包括pp1和pp2两个推送进程,该两个推送进程分别用于拉取part1和part2中的消息,该两个推送进程不会同时拉取同一分区(part1或part2)中的消息;对于group2,如果其包括推送进程pp3和pp4,则pp3可重复拉取part1中的消息,pp4可重复拉取part2中的消息或者根据需要也可拉取part3中的消息。

对于单个组,其是由多台推送服务器上启动的推送进程组成,同一组中多台推送服务器上的推送进程会争抢分区并消费争抢到的分区,如果组中某台推送服务器挂掉,它所消费的分区就会被其它推送服务器抢走,从而保证了服务稳定。为提高推送服务器利用率,组和推送服务器之间可以是多对多关系,即一台推送服务器上可布署多个消费组,一个消费组布署在多台推送服务器上。当然,也可以只启动一台推送服务器,在这一台推送服务器上布署多个消费组。

需要说明的是,本发明实施例中的消费者,不是某个用户,而是某个业务系统,比如结算系统或库存系统,该消息队列的使用场景是业务系统间的异步通信。如前所述,一个业务代表一个组,配置文件中可以配置组名和对应的消费ip列表(业务可以是多台机器),推送服务器会将消费推送到指定ip对应的业务所在的机器。

本实施例的好处在于:

1、代理服务器接收到的业务方的消息中包含有关联业务标识位,代理服务器根据消息中的关联业务标识位将消息存储至kafka消息存储系统的对应分区,从而保证相同关联业务标识位的消息按时序进入到同一分区;

2、现有的kafka通常按通道(分区即视为通道)来保证时序,而本发明中每个推送进程中的分区消费者线程在将消息分配给消息推送子线程时,会记录消息推送子线程与消息的关联业务标识位的对应关系,并且后续若再有相同关联业务标识位的消息,则仍分配给对应的消息推送子线程,从而保证了关联消息的时序;本发明摆脱了通过通道保证时序的方式,时序粒度更小,并发度更高;

3、每个分区消费者线程采用多个消息推送子线程来处理消息,能够实现对分区并发处理。若想增加并发度,只需调高消息推送子线程数即可。

4、本实施例在kafka的基础上,合理设计了推送服务器侧的架构,推送进程的分区消费者线程采用多消息推送子线程方式处理消息,并且对应设置一个分区消费位置管理器,而非在kafka侧设置统一的分区消费位置管理器,通过这种结构,能够准确管理每个分区消费者线程的消费进度,为实现高并发推送奠定了基础。

综上,本实施例的分布式高并发消息队列推送系统,在原通道的基础上,重新定义时序粒度,对单个通道进行细致化拆分,提供了更大层度的并发推送方案。本实施例无需通过拆分消息存储通道来提高并发,只需调高消息推送子线程数或者增加推送进程即可提高并发,成本低,灵活性高,能够在保证业务时序要求的同时实现队列消息的高并发推送。

为提高代理服务器的处理能力,代理服务器可以采用集群式布署。为提高系统的稳定性和使用方便性,代理服务器启动后可以与kafka消息存储系统建立长连,并提供网页服务器webserver服务供业务方调用。另外,代理服务器中还可以包括消息处理器(messagehandler),以对收到的消息格式化处理后再存入kafka消息存储系统。

优选的,每个推送服务器启动时即初始化i*j个推送进程,其中i为kafka消息存储系统中分区数,j为所述kafka消息存储系统中消费者组名数量。这样,可以使整个系统的并发处理效率达到最优状态。具体的,每个推送服务器可以在启动时根据分组数创建同等数量的推送进程,创建出来的每个推送进程与同组的推送进程争抢kafka分区,根据争抢到的分区数分支(fork)出与争抢到的分区同等数量的推送进程。

如图1所示,分布式高并发消息队列推送系统还可以包括消费位置推送失败记录区zk,以便于记录推送失败的消息并在后续重新推送出去。该消费位置推送失败记录区zk的目录规则优选为组名/分区/消费位置(例如:/group/part/offset);若重启服务或者消息推送服务器集群中添加了新的推送进程导致重新分配kafka消息存储系统分区,则根据分配到的分区号及组名去对应的消费位置推送失败记录区加载失败的消息进行推送。

为提高系统的服务监控能力,每个推送服务器还可以包括用于监控其上每个推送进程中分区消费者线程状态的网页服务器webserver。该webserver一个功能是负责监控每个分区消费者线程状态,能显示所有异常的消息推送子线程列表、异常消息推送子线程当前消费的消息详情、当前分区消费者线程消费的位置和当前kafka分区存储的最大消息位置。另一功能是当某条消息下游想要丢弃时,可通过跳消息接口跳过该消息。

对于消费位置offset管理,优选的,当分区消费位置管理器接收到推送成功或失败的消费位置状态时,扫描队列,取推送成功和推送失败相连续的最大位置提交到kafka消息存储系统,以使得下次从kafka消息存储系统拉取消息时从该位置拉取。

下面采用两个具体的实施例,对本发明的技术方案进行详细说明。

实施例一:以一个订单消息为例描述本发明中的通道并发详细设计

本实施例一包括以下步骤:

步骤1:订单系统通过http请求将一条订单创建消息发送到代理服务器;

步骤2代理服务器根据消息中的关联业务标识位abid(例如数值为1567)以及kafka分区数来选择存储到具体的kafka某个分区a;

步骤3:监听kafka分区a的某个分区消费者线程partconsumera获取到了消息,找到启动时开辟好的n个消息推送子线程中的某个空闲消息推送子线程winl,并将消息发送给该winl,记录下该win1当前处理的消息abid;

步骤4:该win1监听到了有消息进入,则从内存中加载出配置好的下游消费实例列表,按顺序取其中的一个实例进行消息推送;

步骤5:此时订单系统向代理服务器发送了另一条订单创建消息,代理服务器接到消息后将该消息发送给分区a或其他分区;

步骤6:如步骤3,如果该消息到达分区a,最终处理该消息的将是消息推送子线程win1外的其它空闲消息推送子线程;如果该消息到达其他分区,则由其他推送进程的空闲消息推送子线程来处理;至此完成了对多个分区并发处理的流程。若想增加并发度,调高消息推送子线程数或者增加推送进程即可。

步骤7:此时订单系统向代理服务器又发送了一条与第一条消息abid相同的完成订单命令,由于abid相同,代理服务器分配给了相同的kafka分区,导致同一个分区消费者线程partconsumera拿到了消息,推送进程根据存储的消息推送子线程和消息abid对应关系,将该消息分配给了同一个消息推送子线程。该完成订单命令暂存在消息推送子线程私有队列中排队,等待第一条消息推送成功后再推送。至此满足了关联消息有时序的需求。

实施例二:本发明中的通道消费位置管理详细设计

本实施例二包括以下步骤:

步骤1:某分区消费者线程partconsumer获取到了三条消费位置消息,offset位置分别为1、2、3;

步骤2:假如位置1推送失败,2推送成功,3推送中,按照推送成功和推送失败相连续的最大位置规则(连续是指:当只有推送成功时,取连续推送成功的最大位置,当只有推送失败时,取连续推送失败的最大位置;当既有推送成功和推送失败时,取两者连续的最大位置;当还包括待推送时,待推送位置为不连续),此时offsetmanager会提交2到kafka,并将1记录到消费位置推送失败记录区zk。此时若重启或推送服务器集群中添加了推送进程导致kafka分区重新分配,分配到该分区的partconsumer会先加载zk中的消息1,再从kafka分区中从位置3(即推送成功和推送失败相连续的最大位置2加1)开始读取。实际场景中单条消息消费失败的比例比较小,此方案解决了1推送失败重启后2会重复推送的问题。

需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。

以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以权利要求的保护范围为准。

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