一种消息队列及消费者动态创建方法及系统转让专利

申请号 : CN202110692394.1

文献号 : CN113495797B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 牛如兵成圣昌刘国亮

申请人 : 上海百秋新网商数字科技有限公司

摘要 :

本发明公开了一种消息队列及消费者动态创建方法及系统,包括:S1:在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各业务项目自动创建各租户的专属消息队列及消费者。本发明利用主动创建和被动创建租户的专属消息队列及消费者,确保不同租户之间数据隔离的同时,提高消费者服务的可靠性以及提升消费者服务的吞吐量。

权利要求 :

1.一种消息队列及消费者动态创建方法,其特征在于,包括:

S1:在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各所述业务项目自动创建各所述租户的专属消息队列及消费者;

S2:根据各所述业务项目预设的消费者监听类,对所述SaaS系统创建新租户的主题消息进行监听;根据所述MQ动态配置规则以及所监听的主题消息,扫描所述业务项目所使用自定义消息队列注解的消费者方法,在各所述业务项目中为新增租户创建专属消息队列及消费者;

S3:在新增业务项目初始化启动时,根据MQ动态配置规则,利用配置类自动捕获所使用自定义消息队列注解的消费者方法,在所述新增业务项目中为每个租户生成专属消息队列及消费者;所述所使用自定义消息队列注解的消费者方法在扫描得到的所有所述业务项目中所有类下的所有方法中捕获;所述自定义消息队列注解中携带有队列名和RouteKey;通过获取注解中携带的队列名和RouteKey,模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接租户唯一标识码Code,以此在所述新增业务项目中为每个租户生成专属消费者;所述唯一标识码Code基于在所述SaaS系统中创建的所述新租户的主题消息确定得到。

2.如权利要求1所述的消息队列及消费者动态创建方法,其特征在于,在所述步骤S2中,还包括在接收到创建新租户的主题消息时,调用创建消费者接口,并在消费者类的消费方法上使用所述自定义消息队列注解。

3.如权利要求1所述的消息队列及消费者动态创建方法,其特征在于,在所述SaaS系统创建新租户的主题消息中,携带有新租户的唯一标识码Code,并通过推送到队列中,通知各所述业务项目创建新租户的专属消息队列及消费者。

4.如权利要求3所述的消息队列及消费者动态创建方法,其特征在于,在所述步骤S2中,各所述业务项目通过编写创建消费者接口,模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接新租户的所述唯一标识码Code,以此为新租户生成专属消息队列及消费者。

5.如权利要求3所述的消息队列及消费者动态创建方法,其特征在于,在所述步骤S3中,利用配置类自动捕获使用所述自定义消息队列注解的消费者方法包括在所述新增业务项目的消费者类中的消费方法上使用所述自定义消息队列注解,并通过SpringBoot框架的配置类,以查询所述SaaS系统中所有租户的唯一标识码Code。

6.一种消息队列及消费者动态创建系统,采用如权利要求1‑5所述的方法,其特征在于,包括:规则配置模块、第一创建模块、第二创建模块,所述规则配置模块分别与所述第一创建模块、所述第二创建模块连接;

所述规则配置模块配置为在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各所述业务项目自动创建各所述租户的专属消息队列及消费者;

所述第一创建模块配置为根据各所述业务项目预设的消费者监听类,对所述SaaS系统创建新租户的主题消息进行监听;根据所述MQ动态配置规则以及所监听的主题消息,扫描所述业务项目所使用自定义消息队列注解的消费者方法,在各所述业务项目中为新增租户创建专属消息队列及消费者;

所述第二创建模块配置为在新增业务项目初始化启动时,根据MQ动态配置规则,利用配置类自动捕获所使用自定义消息队列注解的消费者方法,在所述新增业务项目中为每个租户生成专属消息队列及消费者。

7.如权利要求6所述的消息队列及消费者动态创建系统,其特征在于,还包括租户新增模块,所述租户新增模块与所述第一创建模块连接;所述租户新增模块配置为在SaaS系统中创建新租户,并向所述第一创建模块推送新增租户的主题消息。

8.如权利要求6所述的消息队列及消费者动态创建系统,其特征在于,还包括业务新增模块,所述业务新增模块与所述第二创建模块连接;所述业务新增模块配置为在RabbitMq消息队列中创建新业务项目,并推送给所述第二创建模块配置。

说明书 :

一种消息队列及消费者动态创建方法及系统

技术领域

[0001] 本发明涉及计算机技术领域,尤其一种消息队列及消费者动态创建方法及系统。

背景技术

[0002] SaaS,是Software‑as‑a‑Service的缩写名称,意思为软件即服务,即通过网络提供软件服务。SaaS平台供应商将应用软件统一部署在自己的服务器上,客户可以根据工作实际需求,通过互联网向厂商定购所需的应用软件服务,按定购的服务多少和时间长短向厂商支付费用,并通过互联网获得Saas平台供应商提供的服务。
[0003] 多租户(Multi Tenancy/Tenant)SaaS是一种软件系统架构,实现一个平台同时为多个租户提供服务。在该种系统架构上,多个租户共享同样的硬件配置和应用程序,并实现数据的隔离。应用程序被设计成能将自己的数据、配置进行虚拟的分区,以便每个租户都感觉到自己是在一个私有的、可定制化的应用实例上工作。
[0004] 现有电商平台基于多租户SaaS概念开发,旨在可以为成千上万不同的租户提供服务。电商平台可包括网页服务、数据服务、管理服务,网页服务用于存储用户浏览购买商品跟踪订单的页面,数据服务用于为网页服务的页面提供商品、用户、订单、支付等一系列数据,管理服务用于管理商品、用户、订单、支付账务等一系列数据。电商领域中通过消息队列提高用户体验和吞吐量。
[0005] 消息队列(Message queue)可以对传输过程中的消息进行保存,使得消息由消息发送方(或称为生产者)发出后暂存于消息队列中,而无需立即传递至消息接收方(或称为消费者),从而实现消息发送方与消息接收方之间的异步通信。传统电商平台中消息队列的使用,往往是多个租户共用一个消息队列以及共用一个消费者,然而不同租户的业务需求量不同,例如租户A数据量大,租户B数据量小,在并发时可能会出现由于租户A的数据量过大无法在短时间内处理完,导致租户B的数据一直阻塞在队列中得不到处理,影响用户体验。

发明内容

[0006] 本申请实施例通过提供一种消息队列及消费者动态创建方法及系统,解决了现有技术中多租户SaaS系统架构内,由于某些租户出现业务处理量过大时,导致其他租户的业务数据无法及时得到处理的问题,本技术方案通过为每个租户配置专属消息队列及消费者,实现数据隔离的同时,提高消费者服务的吞吐量。
[0007] 第一方面,本申请实施例提供了一种消息队列及消费者动态创建方法,包括:
[0008] S1:在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各所述业务项目自动创建各所述租户的专属消息队列及消费者;
[0009] S2:根据各所述业务项目预设的消费者监听类,对所述SaaS系统创建新租户的主题消息进行监听;根据所述MQ动态配置规则以及所监听的主题消息,扫描所述业务项目所使用自定义消息队列注解的消费者方法,在各所述业务项目中为新增租户创建专属消息队列及消费者;
[0010] S3:在新增业务项目初始化启动时,根据MQ动态配置规则,利用配置类自动捕获所使用自定义消息队列注解的消费者方法,在所述新增业务项目中为每个租户生成专属消息队列及消费者;所述所使用自定义消息队列注解的消费者方法在扫描得到的所有所述业务项目中所有类下的所有方法中捕获;所述自定义消息队列注解中携带有队列名和RouteKey;通过获取注解中携带的队列名和RouteKey,模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接租户唯一标识码Code,以此在所述新增业务项目中为每个租户生成专属消费者;所述唯一标识码Code基于在所述SaaS系统中创建的所述新租户的主题消息确定得到。
[0011] 进一步地,在所述步骤S2中,还包括在接收到创建新租户的主题消息时,调用创建消费者接口,并在消费者类的消费方法上使用所述自定义消息队列注解。
[0012] 进一步地,在所述SaaS系统创建新租户的主题消息中,携带有新租户的唯一标识码Code,并通过推送到队列中,通知各所述业务项目创建新租户的专属消息队列及消费者。
[0013] 进一步地,在所述步骤S2中,各所述业务项目通过编写创建消费者接口,模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接新租户的所述唯一标识码Code,以此为新租户生成专属消息队列及消费者。
[0014] 进一步地,在所述步骤S3中,利用配置类自动捕获使用所述自定义消息队列注解的消费者方法包括在所述新增业务项目的消费者类中的消费方法上使用所述自定义消息队列注解,并通过SpringBoot框架的配置类,以查询所述SaaS系统中所有租户的唯一标识码Code。
[0015] 第二方面,本申请实施例提供了一种消息队列及消费者动态创建系统,采用第一方面所述的方法,包括:规则配置模块、第一创建模块、第二创建模块,所述规则配置模块分别与所述第一创建模块、所述第二创建模块连接;
[0016] 所述规则配置模块配置为在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各所述业务项目自动创建各所述租户的专属消息队列及消费者;
[0017] 所述第一创建模块配置为根据各所述业务项目预设的消费者监听类,对所述SaaS系统创建新租户的主题消息进行监听;根据所述MQ动态配置规则以及所监听的主题消息,扫描所述业务项目所使用自定义消息队列注解的消费者方法,在各所述业务项目中为新增租户创建专属消息队列及消费者;
[0018] 所述第二创建模块配置为在新增业务项目初始化启动时,根据MQ动态配置规则,利用配置类自动捕获所使用自定义消息队列注解的消费者方法,在所述新增业务项目中为每个租户生成专属消息队列及消费者。
[0019] 进一步地,还包括租户新增模块,所述租户新增模块与所述第一创建模块连接;所述租户新增模块配置为在SaaS系统中创建新租户,并向所述第一创建模块推送新增租户的主题消息。
[0020] 进一步地,还包括业务新增模块,所述业务新增模块与所述第二创建模块连接;所述业务新增模块配置为在RabbitMq消息队列中创建新业务项目,并推送给所述第二创建模块配置。
[0021] 第三方面,本公开实施例提供了一种电子设备,包括存储器和处理器;其中,所述存储器用于存储一条或多条计算机指令,其中,所述一条或多条计算机指令被所述处理器执行以实现第一方面所述的方法步骤。
[0022] 第四方面,本公开实施例提供了一种计算机可读存储介质,用于存储消息中间件的消息传递装置所用的计算机指令,其包含用于执行上述第一方面中消息中间件的消息传递方法所涉及的计算机指令。
[0023] 本申请实施例中提供的技术方案,至少具有如下技术效果:
[0024] (1)解决了SaaS系统在传统消息队列设计中的吞吐量堵塞的问题,利用消息队列MQ技术,为多租户SaaS系统中的各个租户动态创建专属消息队列及消费者,确保不同租户之间数据隔离的同时,提高消费者服务的可靠性以及提升消费者服务的吞吐量。
[0025] (2)利用本技术方案中的MQ动态配置规则后,开发人员无需对所有租户分别编写代码,仅需设置MQ动态配置规则后,在新增租户或者新增业务项目时,直接创建业务项目对应租户的专属消息队列及消费者,降低开发人员工作量的前提下,以简单的配置规则提供一种消息队列中数据隔离的解决方案。
[0026] 应当理解的是,以上的一般描述和后文的细节描述仅是示例性和解释性的,并不能限制本公开。

附图说明

[0027] 图1为本申请实施例1中一种消息队列及消费者动态创建方法流程图;
[0028] 图2为本申请实施例1中多租户SaaS系统适用的一种架构示意图;
[0029] 图3为本申请实施例1中多租户与业务项目之间的连接关系架构图;
[0030] 图4为本申请实施例1中多租户与单个业务项目之间的连接关系架构图;
[0031] 图5为本申请实施例1中单个租户与多个业务项目之间的连接关系架构图;
[0032] 图6为本申请实施例2中一种消息队列及消费者动态创建系统框图。

具体实施方式

[0033] 为了更好的理解上述技术方案,下面将结合说明书附图以及具体的实施方式对上述技术方案进行详细的说明。
[0034] 本发明中涉及到的科技术语解释说明如下:
[0035] SaaS:软件即服务;MQ:消息队列;RabbitMQ:消息队列中间件;Spring:Spring框架;RouteKey:路由匹配关键字;Code:租户唯一标识码;SpringBoot:SpringBoot框架。
[0036] 本申请实施例通过提供一种消息队列及消费者动态创建方法及系统,解决了现有技术中多租户SaaS系统架构内,由于某些租户出现业务处理量过大时,导致其他租户的业务数据无法及时得到处理的问题,本技术方案通过为每个租户配置专属消息队列及消费者,实现数据隔离的同时,提高消费者服务的吞吐量。为了使本技术领域的人员更好地理解本申请中的技术方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本申请保护的范围。
[0037] 实施例1
[0038] 参考图1所示,为本申请实施例提供的一种消息队列及消费者动态创建方法流程图,本实施例提供的一种消息队列及消费者动态创建方法,包括如下步骤。
[0039] 步骤S1:在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各业务项目自动创建各租户的专属消息队列及消费者。
[0040] 本实施例利用消息队列技术,基于多租户系统对数据传输方式进行的改进。参考图2所示,为多租户SaaS系统适用的一种架构示意图。多个租户将数据通过Web Server传输到数据库中存储,以供服务。本实施例基于多租户SaaS系统中,对数据传输以及吞吐量进行改进优化。参考图3‑5所示,为本申请实施例所适用的多租户与业务项目之间的连接关系。
[0041] sendTask方法体表示为发送任务,业务项目以及租户任意一个出现动态变化时,根据自定义消息队列注解,为各业务项目自动创建各租户的专属消息队列及消费者。参考图4、5所示,当新增租户时,为每个业务项目创建该新增租户的专属消息队列及消费者,当新增业务项目时,为新增的业务项目创建所有租户在该新增业务项目中的专属消息队列及消费者。
[0042] 步骤S2:根据各业务项目预设的消费者监听类,对SaaS系统创建新租户的主题消息进行监听;根据MQ动态配置规则以及所监听的主题消息,扫描业务项目所使用自定义消息队列注解的消费者方法,在各业务项目中为新增租户创建专属消息队列及消费者。
[0043] 本实施例中,在SaaS系统创建新租户的主题消息中,携带有新租户的唯一标识码Code,并通过推送到队列中,通知各业务项目创建新租户的专属消息队列及消费者。当然,在已有的租户所绑定的消息队列及消费者中,也携带有租户的位移标识码Code。
[0044] 在步骤S2中,还包括在接收到创建新租户的主题消息时,调用创建消费者接口,并在消费者类的消费方法上使用自定义消息队列注解。即为在消费者类的消费方法中设置有MQ动态配置规则。
[0045] 在步骤S2中,各业务项目通过编写创建消费者接口,模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接新租户的唯一标识码Code,以此为新租户生成专属消息队列及消费者。进一步地,本步骤中编写创建消费者的接口,模拟消息队列中间件RabbitMq注册消费者到Spring框架容器的过程,在队列名和路由匹配关键字RouteKey前拼接租户唯一标识码Code,以此在每个业务项目中为新增租户创建专属消息队列及消费者。
[0046] 步骤S2中主要表现为,在新增租户时,各个业务项目中根据MQ动态配置规则主动创建与新增租户的连接关系,即为新增租户创建专属消息队列及消费者,使得通过SaaS系统访问新增租户的信息时,直接通过专属消息队列及消费者即可快速处理相应的业务项目。
[0047] 进一步地,主动创建租户专属消息队列及消费者的步骤可以包括:
[0048] S21:编写自定义消息队列注解,注解携带队列名和RouteKey,用于之后创建队列和消费者。
[0049] S22:在新增租户时,推送创建新租户的主题消息至队列中,该消息携带该新租户的唯一标识码Code,通知各业务项目创建消费者。代码如下:
[0050] public void initMessageListenerContainerForCreateTenant(String tenantCode){try{ConnectionFactory  connectionFactory=getRabbitConnectionFactory();RabbitAdmin rabbitAdmin=getRabbitAdmin();AbstractRabbitListenerContainerFactory simpleRabbitListenerContainerFactory=getRabbitListenerContainerFactory(connectionFactory);
[0051] RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry=new RabbitListenerEndpointRegistry();rabbitListenerEndpointRegistry.start();
[0052] RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar=new RabbitListenerEndpointRegistrar();
[0053] SetqueueNameSet=new HashSet<>();
[0054] Method[ ]declaredMethods=null;CustomRabbitListener customRabbitListener=null;RabbitListenerEnum rabbitListenerConfig=null;
String className=null;String methodName=null;Object bean=null;String queueName=null;String routeKey=null;
[0055] String simpleRabbitListenerEndpointId=null;Queue queue=null;SimpleRabbitListenerEndpointsimpleRabbitListenerEndpoint=null;Set>classSet=ClassUtil.scanPackage("com.ibaiqiu");
[0056] ……
[0057] S23:在每个业务项目编写一个监听消费者,用于监听创建新租户的消息,当收到消息时,调用创建消费者的接口,在消费者类中的消费方法上使用自定义消息队列注解。
[0058] S24:编写创建消费者的接口,模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接租户唯一标识码Code,以此来为该新租户生成专属的消费者。
[0059] 在SaaS系统中创建新租户,包括设置新租户的唯一标识码、名称、简称、状态以及功能权限在内的多个租户信息,其中功能权限包括租户所使用平台、内容、商品、营销、订单等等。创建完成后,SaaS系统自动推送创建新租户的主题消息至所有队列中,队列收到消息后,会调用创建消费者的接口,模拟RabbitMq(消息队列中间件)注册消费者到Spring(Spring框架)容器的过程,在队列名和RouteKey(路由匹配关键字)前拼接租户唯一标识Code(唯一标识Code码),为该新租户生成专属的消费者,此时测试商户1的所有数据都将会推送到带有其唯一标识Code(唯一标识Code码)前缀的队列中。
[0060] 步骤S3:在新增业务项目初始化启动时,根据MQ动态配置规则,利用配置类自动捕获所使用自定义消息队列注解的消费者方法,在新增业务项目中为每个租户生成专属消息队列及消费者。
[0061] 在步骤S3中,利用配置类自动捕获使用自定义消息队列注解的消费者方法包括在新增业务项目的消费者类中的消费方法上使用自定义消息队列注解,并通过SpringBoot框架的配置类,以查询SaaS系统中所有租户的唯一标识码Code。
[0062] 步骤S3进一步包括扫描所有业务项目中所有类下的所有方法,找出使用自定义消息队列注解的消费者方法,获取注解中携带的队列名和RouteKey;模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接租户唯一标识码Code,以此在新增业务项目中为每个租户生成专属消费者。
[0063] 本实施例中的步骤S3是消息队列及消费者被动创建过程,其可以包括如下步骤。
[0064] S31:编写自定义消息队列注解,在消费者类中的消费方法上使用自定义消息队列注解,注解携带队列名和RouteKey,用于之后创建消息队列和消费者。
[0065] 如下代码表示在消费者类中的消费方法上使用自定义消息队列注解。
[0066] @Component
[0067] public class UserLoginLogSaveListener{
[0068] private static final String IP_ADDRESS_ANALYSIS_URL="http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=";
[0069] private static final String IP_ADDRESS_AREA="addr";
[0070] private static final String UNKNOWN_IP_ADDRESS_AREA="未知";
[0071] @Autowired
[0072] private UserLoginLogDao userLoginLogDao;
[0073] @ManualAck(requeue=false)
[0074] @CustomRabbitListener(rabbitListenerConfig=RabbitListenerEnum.USER_LOGIN_LOG_SAVE_LISTENER)
[0075] public void saveUserLoginLog(Message message,Channel channel)throws Exception{
[0076] UserLoginLog userLoginLog=JSONObject.parseObject(message.getBody(),UserLoginLog.class);
[0077] String ipAddress=userLoginLog.getIpAddress();
[0078] AssertUtil.fastAssert(ReturnCode.USER_IP_ADDRESS_IS_NULL,ipAddress);
[0079] MapresultMap=HttpClientUtils.getResult(IP_ADDRESS_ANALYSIS_URL+ipAddress,newTypeReference>(){});
[0080] if(AssertUtil.isNull(resultMap)||AssertUtil.isNull(resultMap.get(IP_ADDRESS_AREA)))
[0081] {userLoginLog.setIpAddressArea(UNKNOWN_IP_ADDRESS_AREA);}else[0082] {userLoginLog.setIpAddressArea(resultMap.get(IP_ADDRESS_AREA));}userLoginLogDao.insertSelective(userLoginLog)}}
[0083] S32:编写SpringBoot配置类,查询SaaS系统中所有租户的唯一标识码Code。
[0084] 编写SpringBoot配置类的代码如下:
[0085] “@Component@Order(value=2)private class InitMessageListenerContainer implements CommandLineRunner{@Overridepublic void run(String...args)throws Exception{try{ConnectionFactory connectionFactory=getRabbitConnectionFactory();RabbitAdmin rabbitAdmin=getRabbitAdmin();AbstractRabbitListenerContainerFactorysimpleRabbitListenerContainerFactory=getRabbitListenerContainerFactory(connectionFactory);
[0086] RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry=newRabbitListenerEndpointRegistry();rabbitListenerEndpointRegistry.start();RabbitListenerEndpointRegistrarrabbitListenerEndpointRegistrar=newRabbitListenerEndpointRegistrar( ) ;DynamicDataSource .setDataSource(Constant.DataSource.PLATFORM_DATASOURCE);
[0087] ListtenantCodeList=tenantDao.getTenantCodeList();”。
[0088] S33:扫描业务项目中的所有类下的所有方法,找到使用了自定义消息队列注解的消费者方法,并获取注解中携带的队列名和RouteKey。
[0089] 其中,判断是否开启多数据源模式中,代码如“if(RabbitListenerEnum.MultipleDataSourceMode.ON==rabbitListenerConfig.getMultipleDataSourceMode()”。
[0090] 进一步地,开启多数据源模式,遍历所有租户,在队列名和路由Key前拼接租户Code为每个租户生成对应消费者,代码分析如下:
[0091] “for(String tenantCode:tenantCodeList){queueName=(rabbitListenerConfig.getMultipleNodeMode()?ipAddressPrefix:StrUtil.EMPTY)+tenantCode+StrUtil.DOT+rabbitListenerConfig.getQueue();routeKey=tenantCode+StrUtil.DOT+rabbitListenerConfig.getRouteKey();simpleRabbitListenerEndpointId=(rabbitListenerConfig.getMultipleNodeMode()?ipAddressPrefix:StrUtil.EMPTY)+tenantCode+StrUtil.DOT+className+StrUtil.DOT+methodName;registerListenerContainer(queueNameSet,queueName,queue,rabbitAdmin,rabbitListenerConfig,routeKey,simpleRabbitListenerEndpoint,
simpleRabbitListenerEndpointId,method,bean,simpleRabbitListenerContainerFactory,rabbitListenerEndpointRegistry);}”。
[0092] 其中,针对未开启多数据源模式,不进行任何拼接,直接生成消费者,代码分析如下:
[0093] “queueName=(rabbitListenerConfig.getMultipleNodeMode()?ipAddressPrefix:StrUtil.EMPTY)+rabbitListenerConfig.getQueue();routeKey=rabbitListenerConfig.getRouteKey();simpleRabbitListenerEndpointId=(rabbitListenerConfig.getMultipleNodeMode()?ipAddressPrefix:StrUtil.EMPTY)+className+StrUtil.DOT+methodName;registerListenerContainer(queueNameSet,queueName,queue,rabbitAdmin,rabbitListenerConfig,routeKey,simpleRabbitListenerEndpoint,simpleRabbitListenerEndpointId,method,bean,simpleRabbitListenerContainerFactory,rabbitListenerEndpointRegistry);”。
[0094] S34:模拟RabbitMq注册消费者到Spring容器的过程,在队列名和RouteKey前拼接租户唯一标识Code码,以此来为每个租户生成专属的消费者。
[0095] 实施例2
[0096] 参考附图6所示,本申请实施例提供了一种消息队列及消费者动态创建系统,采用如实施例1中的方法,其包括规则配置模块100、第一创建模块200、第二创建模块300,规则配置模块100分别与第一创建模块200、第二创建模块300连接。
[0097] 规则配置模块100配置为在多租户SaaS系统中,为各业务项目和各租户之间构建MQ动态配置规则,通过在sendTask方法体上自定义消息队列注解,为各业务项目自动创建各租户的专属消息队列及消费者。
[0098] 第一创建模块200配置为根据各业务项目预设的消费者监听类,对SaaS系统创建新租户的主题消息进行监听;根据MQ动态配置规则以及所监听的主题消息,扫描业务项目所使用自定义消息队列注解的消费者方法,在各业务项目中为新增租户创建专属消息队列及消费者。
[0099] 第二创建模块300配置为在新增业务项目初始化启动时,根据MQ动态配置规则,利用配置类自动捕获所使用自定义消息队列注解的消费者方法,在新增业务项目中为每个租户生成专属消息队列及消费者。
[0100] 本实施例还包括租户新增模块400,租户新增模块400与第一创建模块200连接;租户新增模块400配置为在SaaS系统中创建新租户,并向第一创建模块200推送新增租户的主题消息。
[0101] 本实施例还包括业务新增模块500,业务新增模块500与第二创建模块300连接;业务新增模块500配置为在RabbitMq消息队列中创建新业务项目,并推送给第二创建模块300配置。
[0102] 实施例3
[0103] 本实施例提供了一种电子设备,包括存储器和处理器;其中,所述存储器用于存储一条或多条计算机指令,其中,所述一条或多条计算机指令被处理器执行以实现实施例1的方法步骤。
[0104] 本实施例提供了一种计算机可读存储介质,其上存储有计算机指令,该计算机指令被处理器执行时实现实施例1的方法步骤。
[0105] 对于一个技术的改进可以很明显地区分是硬件上的改进(例如,对二极管、晶体管、开关等电路结构的改进)还是软件上的改进(对于方法流程的改进)。然而,随着技术的发展,当今的很多方法流程的改进已经可以视为硬件电路结构的直接改进。设计人员几乎都通过将改进的方法流程编程到硬件电路中来得到相应的硬件电路结构。因此,不能说一个方法流程的改进就不能用硬件实体模块来实现。例如,可编程逻辑器件(Programmable Logic Device,PLD)(例如现场可编程门阵列(Field Programmable Gate Array,FPGA))就是这样一种集成电路,其逻辑功能由用户对器件编程来确定。由设计人员自行编程来把一个数字系统“集成”在一片PLD上,而不需要请芯片制造厂商来设计和制作专用的集成电路芯片。而且,如今,取代手工地制作集成电路芯片,这种编程也多半改用“逻辑编译器(logic compiler)”软件来实现,它与程序开发撰写时所用的软件编译器相类似,而要编译之前的原始代码也得用特定的编程语言来撰写,此称之为硬件描述语言(Hardware Description Language,HDL),而HDL也并非仅有一种,而是有许多种,如ABEL(Advanced Boolean Expression Language)、AHDL(Altera Hardware Description Language)、Confluence、CUPL(Cornell University Programming Language)、HDCal、JHDL(Java Hardware Description Language)、Lava、Lola、MyHDL、PALASM、RHDL(Ruby Hardware Description Language)等,目前最普遍使用的是VHDL(Very‑High‑Speed Integrated Circuit Hardware Description Language)与Verilog2。本领域技术人员也应该清楚,只需要将方法流程用上述几种硬件描述语言稍作逻辑编程并编程到集成电路中,就可以很容易得到实现该逻辑方法流程的硬件电路。
[0106] 控制器可以按任何适当的方式实现,例如,控制器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(Application Specific Integrated Circuit,ASIC)、可编程逻辑控制器和嵌入微控制器的形式,控制器的例子包括但不限于以下微控制器:ARC 625D、Atmel AT91SAM、Microchip PIC18F26K20以及Silicone Labs C8051F320,存储器控制器还可以被实现为存储器的控制逻辑的一部分。本领域技术人员也知道,除了以纯计算机可读程序代码方式实现控制器以外,完全可以通过将方法步骤进行逻辑编程来使得控制器以逻辑门、开关、专用集成电路、可编程逻辑控制器和嵌入微控制器等的形式来实现相同功能。因此这种控制器可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置也可以视为硬件部件内的结构。或者甚至,可以将用于实现各种功能的装置视为既可以是实现方法的软件模块又可以是硬件部件内的结构。
[0107] 上述实施例阐明的系统、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。
[0108] 为了描述的方便,描述以上装置时以功能分为各种单元分别描述。当然,在实施本申请时可以把各单元的功能在同一个或多个软件和/或硬件中实现。
[0109] 本领域内的技术人员应明白,本发明的实施例可提供为方法、系统、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD‑ROM、光学存储器等)上实施的计算机程序产品的形式。
[0110] 本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
[0111] 这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
[0112] 这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
[0113] 在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
[0114] 内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
[0115] 计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD‑ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
[0116] 还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括要素的过程、方法、商品或者设备中还存在另外的相同要素。
[0117] 本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于系统实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
[0118] 以上仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。