CN115357413A - 一种使规则引擎实例进行水平扩展的控制系统 - Google Patents
一种使规则引擎实例进行水平扩展的控制系统 Download PDFInfo
- Publication number
- CN115357413A CN115357413A CN202211055432.3A CN202211055432A CN115357413A CN 115357413 A CN115357413 A CN 115357413A CN 202211055432 A CN202211055432 A CN 202211055432A CN 115357413 A CN115357413 A CN 115357413A
- Authority
- CN
- China
- Prior art keywords
- event
- rule
- instance
- rule engine
- cluster
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/54—Interprogram communication
- G06F9/542—Event management; Broadcasting; Multicasting; Notifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/14—Error detection or correction of the data by redundancy in operation
- G06F11/1479—Generic software techniques for error detection or fault masking
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/50—Allocation of resources, e.g. of the central processing unit [CPU]
- G06F9/5083—Techniques for rebalancing the load in a distributed system
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02P—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN THE PRODUCTION OR PROCESSING OF GOODS
- Y02P90/00—Enabling technologies with a potential contribution to greenhouse gas [GHG] emissions mitigation
- Y02P90/02—Total factory control, e.g. smart factories, flexible manufacturing systems [FMS] or integrated manufacturing systems [IMS]
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Quality & Reliability (AREA)
- Multimedia (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明公开了一种使规则引擎实例进行水平扩展的控制系统,包括上游事件来源、下游业务系统、事件序列总线组、时间同步模块、规则引擎集群以及规则输出总线组,本发明的有益效果是,一、通过使用基于请求/应答的消息传输模式,实现对单点部署和集群扩展中的因宕机而错误的情况进行检查;二、通过使用基于轮换的传输控制机制,实现将事件序列中包含的多个有重叠的业务负载,分散到集群内多个节点当中;三、通过使用基于时间窗口的滚动机制,实现对因其他异常导致的处理结果错误进行纠错;四、提出三种不同的方案,分别满足了规则引擎集群扩展过程中对高性能、均衡、和强一致性三个方面的不同要求。
Description
技术领域
本发明涉及规则引擎水平扩展领域,特别是一种使规则引擎实例进行水平扩展的控制系统。
背景技术
对于一段完整的业务,当前的传统水平扩展方案一般的通用做法是“强制无状态”,即:将这段完整的业务中可以进行分为几个可以切割的阶段,每一阶段进行水平扩展的方式部署,当有新业务流程开始时,依次调用不同的业务阶段,每个阶段处理完成后,都序列化一个形态数据,并交由下一个阶段进行处理。但是这个方案的关键点在于,要能够找到可以进行序列化的业务数据,并且每个业务阶段对业务数据的修改不依赖于其他同类业务的不同业务阶段的处理结果。
而在规则引擎的典型业务场景当中,这样却不可以,比如:在A地的温度传感器(T1)上报温度过高后(此时上报的温度为t1),同在A地的3个烟雾报警器(分别记为S1、S2、S3)中的2个或以上报告了发现烟雾,之后的1分钟内,T1再次上报的温度t2高于t1,则认为A处发生了火灾。此时如果在T1上报t2时,如果没有获取到T1上报的t1或者没有获取到S1、S2、S3当中的任意2个以上,都无法进行正确处理,这样会使平台的业务处理能力和处理难度有很大的提升。
发明内容
本发明的目的是为了解决上述问题,设计了一种使规则引擎实例进行水平扩展的控制系统。
实现上述目的本发明的技术方案为,一种使规则引擎实例进行水平扩展的控制系统,包括上游事件来源、下游业务系统、事件序列总线组、时间同步模块、规则引擎集群以及规则输出总线组;
所述上游事件来源是指其业务处理结果与这个处理结果对应的限定条件一起得到的任何业务系统,为规则引擎系统的所有业务提供业务处理的事件;
所述下游业务系统是指使用规则引擎处理结果进行下一步的业务处理的系统;
所述时间同步模块,所述时间同步模块将所有的总线、模块、实例的本地时间进行同步,保证系统内时间一致。
所述事件序列总线组由多个事件序列总线组成,共同负责为规则引擎集群中实例集群内的各个节点或者节点组提供事件序列,每个事件序列总线由事件接收模块、事件消息编码模块、规则配置与分析模块、分散负载模块(分散负载模块中包含多个分散负载实例)和事件发送模块构成。
所述规则引擎集群内包含实例编码模块和实例集群,其中实例集群可以选择两种策略:当选择互为主备策略时,实例集群内包含多个规则引擎节点;当选择组内冗余策略时,实例集群内包含多个规则引擎节点组。
所述规则输出总线组由多个规则输出总线组成,共同负责将规则引擎集群得到的处理结果进行去重合并与发送。每个规则输出总线当中包含重复触发合并模块与处理结果发送模块。重复触发合并模块中包含多个去重任务,每个任务负责对一个规则进行去重。处理结果发送模块负责将去重合并后的处理结果发送到下游业务系统当中。
所述互为主备的集群部署策略:所有规则引擎实例之间构成互为主备关系,即如果一个实例失效,由集群内另外一个实例接替失效实例进行一次业务处理。
所述组内冗余的集群部署策略:所有的实例从逻辑上分为若干个组,每个组内的实例数量为奇数个,组内各个实例都执行完全相同的业务,若某个节点失效,不会影响组内其他节点,最终一个业务的处理结果以组内节点的大多数节点达成一致为原则。
所述规则引擎集群当选择互为主备策略时,每个实例都是集群内的一个节点,而在选择组内冗余策略时,若干个实例一起构成了集群内的一个节点组。
所述实例编码模块负责对规则引擎实例集群中的实例进行编码,在系统当中通过这个编码来代表某个实例,实例的当前的工作状态、业务处理情况,及处理结果。
利用本发明的技术方案制作的一种使规则引擎实例进行水平扩展的控制系统,一、通过使用基于请求/应答的消息传输模式,实现对单点部署和集群扩展中的因宕机而错误的情况进行检查;二、通过使用基于轮换的传输控制机制,实现将事件序列中包含的多个有重叠的业务负载,分散到集群内多个节点当中;三、通过使用基于时间窗口的滚动机制,实现对因其他异常导致的处理结果错误进行纠错;四、提出三种不同的方案,分别满足了规则引擎集群扩展过程中对高性能、均衡、和强一致性三个方面的不同要求。
附图说明
图1是本发明所述一种使规则引擎实例进行水平扩展的控制系统的系统整体结构图;
图2是本发明所述一种使规则引擎实例进行水平扩展的控制系统的规则引擎集群结构图。
图3是本发明所述一种使规则引擎实例进行水平扩展的控制系统的事件序列总线的结构与流程。
图4是本发明所述一种使规则引擎实例进行水平扩展的控制系统的事件接收模块的结构与流程。
图5是本发明所述一种使规则引擎实例进行水平扩展的控制系统的各个事件消息编码模块的结构与流程。
图6是本发明所述一种使规则引擎实例进行水平扩展的控制系统的规则配置与分析模块的结构与流程。
图7是本发明所述一种使规则引擎实例进行水平扩展的控制系统的规则配置与分析模块的结构与流程。
图8是本发明所述一种使规则引擎实例进行水平扩展的控制系统的事件发送模块的结构与流程。
图9是本发明所述一种使规则引擎实例进行水平扩展的控制系统的事件发送模块的结构与流程。
具体实施方式
下面结合附图对本发明进行具体描述,如图1-9所示,一种使规则引擎实例进行水平扩展的控制系统,规则引擎水平扩展控制系统从上游事件来源接收事件,在其内部进行处理,处理结束后,将处理的结果发送给下游业务系统。其中上游事件来源是为规则引擎系统的所有业务提供业务处理的事件的系统。而下游业务系统是指使用规则引擎处理结果进行下一步的业务处理的系统。
整个控制系统内部分为时间同步、事件序列总线组、规则引擎集群和规则输出总线组4个部分。其中:
事件序列总线组由多个事件序列总线组成,每个事件序列总线由事件接收模块、事件消息编码模块、规则配置与分析模块、分散负载模块(分散负载模块中包含多个分散负载实例)和事件发送模块构成。
规则输出总线组由多个规则输出总线组成,每个规则输出总线当中包含重复触发合并模块与处理结果发送模块,重复触发合并模块中包含多个去重任务。
本发明主要的创新内容在于上面所述事件序列总线组和规则输出总线组两个部分。事件序列总线负责对事件序列进行整理和控制,通过报文将事件信息发送到规则引擎集群当中的各个实例,并且在发送阶段对规则引擎实例失效的情况进行处理。规则输出总线接收到输出报文后,进行整理与合并,对误触发和处理失效的情况进行检查,最终将处理结果通知到下游业务系统。两者与规则引擎集群进行配合,在时间同步模块的支撑下,即可以实现在规则引擎处理这种有状态计算的场景下对业务负载的分散。
现对在本实施方案中系统的整体使用流程,及各个内部模块在此流程当中的具体作用,与模块之间的流转关系进行说明。
首先是部署工作,部署所需的各个组件。部署一些规则引擎实例,“实例编码模块”记录这些实例的信息,部署完成后选择集群策略(互为主备策略和组内冗余策略)。根据选用的集群策略的不同,将这些实例组成节点或节点组,并且由“实例编码模块”对这些节点或节点组进行编码并保存。然后部署若干个“事件序列总线”组成事件序列总线组,部署若干个“规则输出总线”组成规则输出总线组。
其次是配置工作。由用户在“事件序列总线”的“事件接收模块”中配置事件(事件即由上游事件来源可以提供的,包含着具体业务信息的数据),和这个事件指定所属的类别、数据字段和接收方式(主动接收或被动接收)信息。用户配置完事件之后,则在“规则分析与配置模块”当中配置需要进行的处理的规则(规则即在事件序列中,根据规则当中的配置,查看是否有满足条件的事件组合),然后分析此规则,得到每个规则引擎节点或者节点组上应该部署的业务模板,不同的节点或者节点组上需要部署的业务模板都有所不同,将这些模板部署到对应的规则引擎节点或者节点组上。
再次是事件序列的处理工作,由“事件序列总线”执行,为“规则引擎集群”提供事件序列。当事件和规则都配置完成后,“事件接收模块”就会启动任务接收这类事件,接收到事件以后将事件转换成原始事件,并发送给“事件消息编码模块”。“事件消息编码模块”接收到原始事件之后,为其添加有顺序且唯一的编码,并将所有的原始事件按照这个编码进行排序,得到原始事件序列,发送给“分散负载模块”。“分散负载模块”内部会启动多个“分散负载实例”,分别负责为不同的规则收集事件序列。收集到的事件序列由“事件发送模块”发送到规则引擎集群当中。
然后是规则的处理工作,由“规则引擎集群”当中的节点或者节点组执行,为“规则输出总线”提供去重之前的规则输出(即规则的处理结果)。每个规则引擎节点或者节点组各自处理“规则配置与分析模块”为其部署的业务模板,处理完成后将规则输出发送给“规则输出总线”。
最后是规则输出的去重与合并工作,由“规则输出总线”执行,将去重合并后的结果发送到“下游业务系统”。“重复触发合并模块”当中启动了多个去重任务,每个任务对应着一个规则,当成功的去重合并出一条规则输出后,就转化为结果,发送给“处理结果发送模块”,并由其发送给“下游业务系统”。
时间同步模块:用来保障系统当中各个进程使用的系统时间的一致性,时间一致才能保障业务处理的正确性与有效性。时间同步模块对时间同步的级要求保证在毫秒级以上。此模块的具体实现可以使用ntp或者chrony服务来完成,可以选择宿主机或服务进程的时间同步。
规则引擎集群:负责对实际的业务处理,即从事件序列中按照规则配置找出符合条件的事件组合。图2是规则引擎集群的结构图,左右两部分分别展示了互为主备策略和组内冗余策略下规则引擎集群内各个部分的组成和相互之间的交互,该图是图1当中“规则引擎集群”部分的详细展开图。“规则引擎实例集群”由多个规则引擎实例(每个实例都是一个复杂事件处理中间件,本文当中的内容是基于Siddhi进行说明,也可以选择其他的产品,不影响系统进行水平扩展时的正确性)组成,“实例编码模块”负责对这些实例进行编码。
规则引擎实例集群:由若干个规则引擎实例组成,每个实例接收“事件序列总线”发送过来的报文,按照规则的具体配置对事件序列当中的事件进行识别,将成功识别到的事件组合以输出的形式发送给“规则输出总线”。此集群中的各个实例之间无状态,部署工作由运维人员手工进行,并将各个实例的地址存放到实例部署信息表中。规则引擎集群当中的实例有两种不同的部署策略,分别是互为主备策略与组内冗余策略,互为主备的集群部署策略,简称为互为主备策略,优点是所需资源相对较少,缺点是响应时间稍长、纠错速度较慢,适用于规模相对较小的项目。组内冗余的集群部署策略,简称为组内冗余策略,优点是响应时间短、纠错速度快,缺点是所需资源较多,适用于规模比较大的项目。
实例编码模块:负责对规则引擎实例集群中的实例进行编码,在系统当中通过这个编码来代表某个实例。从实例部署信息表中读取各个实例的信息,对其分配一个固定的编号并保存到实例部署信息表当中。当使用组内冗余策略时,还需要分配并保存这个实例属于哪个组,每个组有不同的编号,同一组内处理完全相同的业务。
事件序列总线:图3是事件序列总线的结构与流程图,即图1当中的事件序列总线的详情展开图,说明了事件序列总线内的流程。从各种事件来源获得到的原始事件,都需要由“事件接收模块”进行统一接收。并根据实际接收到的顺序,由“事件消息编码模块”对所有原始事件进行排序与编码,用来形成一个确定的事件序列。在形成确定的事件序列以后,先由“规则配置与分析模块”解析出某规则是否使用了这类事件,如果使用了,则将其取回并排序,形成针对这个规则的稳定事件序列。之后再由“分散负载模块”依照依次轮换的方式,确定每个事件在某规则中的主要处理节点或节点组,被选定的节点或者节点组将优先处理这个事件。在确定处理节点或节点组以后,使用“事件发送模块”将事件转换成报文并发送给各个节点或节点组。此外事件序列总线本身也是水平扩展的,需要对每个事件序列总线赋予总线编号。
事件接收模块:目前事件接收模块接收事件的方式有两种,即主动接收和被动接收。其中:主动接收是指为事件接收模块指定若干个信道,这些信道是其自身业务所需的信道,其与规则引擎的业务无关,事件接收模块会主动去消费这些信道中的信息,将有用的信息收集起来作为原始事件,目前支持查询市面上主流的消息中间件产品中的消息。被动接收是指由上游事件来源通过规则引擎指定的方式,主动的发送给事件接收模块,这种方式有两种具体实现,一是通过在事件接收模块配置,指定消息中间件中若干个topic,二是事件接收模块指定API端口,由上游业务系统将消息内容通过这两种方式之一发送到事件接收模块,事件接收模块便被动的接收到了消息推送。
图4是事件接收模块的结构与流程图,即图3当中事件接收模块的详细展开图,描述了事件接受模块的流程。首先事件的配置工作由用户在事件配置页面上编辑,经过“事件类型配置功能”将配置好的事件保存到数据库。保存完成后,为每一个事件启动“接收事件功能”任务,此任务负责对这类事件的接收工作。接收到的事件使用“原始事件转换功能”转换为系统内部可以使用的原始事件。转换完成后,便会由“原始事件发送功能”发送给事件消息编码模块。接下来分别对这几个功能进行说明
事件类型配置功能:负责对规则引擎可以进行处理或匹配的各种类型的事件进行配置。本功能包括对事件分类的增删改查,包括id、分类名和排序号,保存到事件分类表中;对每个事件进行增删改查,包括id、事件名称、接收方式、信道、事件原始的结构、事件输出的字段列表,保存到事件信息表中。在事件创建完成以后,按照指定的接收方式消费消息或者接收HTTP请求。
接收事件功能:负责接收各上游事件来源产生的各类事件,其中:
主动接收需要在消费topic中数据时,使用一个与原有业务不同的消费组。在事件创建完成以后,使用一个新的消费组,并将此消费组名保存在数据库的事件信息当中(重启任务时,使用保存的消费组进行消费)。然后各个事件序列总线分别开启一个线程(或线程池),对其中的消息进行消费。
被动接收功能在使用消息中间件时,其流程和方式与主动接收所述内容相同。在使用API端口进行接收时,信道是一个HTTP接口地址,由系统生成并分配的。对这些地址的接口进行访问,都会到达API事件消息接收接口中,此接口后端会维持一个对数据库中事件信息表的实时镜像(采用定期刷新全表的方式来保证同步)。此接口在收到请求后,会根据请求地址匹配表中记录,按照匹配结果确定是哪个事件。
原始事件转换功能:负责对接收事件功能接收到事件的原始消息进行识别和转换,根据数据库中事件信息表的配置,确定其属于哪个事件,并按照下面的方法转换:
(1)取出事件原始结构信息,得到事件报文格式;
(2)检查收到的原始消息是否符合事件原始结构字段的配置,如果不符合,则舍弃这条消息并结束,如果符合,则进行下一步;
(3)取出事件输出字段列表信息,取出消息中对应的字段名和字段值,并放到一个新对象当中,为对象添加事件id,拼接完成。
原始事件发送功能:将原始事件发送到事件消息编码模块。创建一个本地队列,将原始事件转换功能产生的对象放入到该队列当中。
事件消息编码模块:负责保障事件序列的稳定性和一致性。在分布式系统当中,请求实际发生的顺序是不可确定的,只要所有节点都按照同样的顺序执行即可,在事件序列总线接收消息时,不作顺序要求和检查,只要保证无丢失即可,而在发送消息时,必须要保证所有的事件序列中事件顺序一致。每个事件消息添加一个全局唯一且有顺序的编号,这个编号就对任意两个事件的排序,编号使用雪花算法得出。编码分为三部分,第一部分是当前时间的毫秒级时间戳,第二部分是流水号,范围从000001到999999,第三部分是当前事件序列总线的节点编号(如从01到99),最终生成一个大整数,将这个整数添加到事件消息当中的serialId字段。
图5是各个事件消息编码模块的具体结构和流程,即图3中事件消息编码模块的详细展开。先由各个事件消息编码模块为原始事件添加serialId字段,将处理好的事件消息发送到Kafka消息中间件当中的不同topic。这些topic都由一个全局唯一的节点消费,这个全局唯一的消费节点是从所有事件序列总线实例中的一个,使用败者树算法,对所有事件消息排序,完成以后发送到kafka中名为sortedEventSeries的topic中,留待分散负载模块从中消费。
规则配置与分析模块:本模块主要有四个功能,“规则配置功能”对整个系统当中需要进行处理的规则进行配置;“规则分析功能”在配置完成后自动分析此规则所需的有几类事件,哪些类型的事件处于起始位置;“接收配置功能”为规则引擎集群中的不同处理节点生成不同的事件接收配置;“部署卸载功能”为提供对规则的部署和卸载功能的支持。图6为规则配置与分析模块的结构和流程,即图3中规则配置与分析模块的详细展开,下面分别对其中各个功能进行具体描述。
规则配置功能:在页面上对规则的信息进行配置,信息包括规则的名称、描述、事件序列的配置、输出字段的配置、是否是连续发生与事件序列的匹配时长(可以为空),同时为规则生成一个ID。将最终的信息保存在数据库的规则信息表中。
规则分析功能:对保存在数据库中规则信息表的规则,取出其事件序列配置,从中解析出此规则都需要使用哪些类别的事件,以及哪几类事件处于起始位置,解析出的信息用于接收配置功能。
接收配置功能:负责根据规则中事件序列的配置与输出字段的配置,生成对应的业务处理模板,这些模板是部署到规则引擎实例上的具体业务要求。首先根据上一步规则分析功能,得到的处于起始位置的几类事件,称为起始事件;然后根据规则引擎集群选用的实例部署策略不同,有2种不同的行为,具体见下一段的描述;最后为规则引擎集群中的不同节点生成了不同的模板,将生成的业务处理模板交给部署卸载功能进行部署。
在使用互为主备的策略时:为起始事件添加直接过滤条件,内容是事件报文的processNodeCode字段的值为节点编号。在规则的输出字段中添加两个字段,其中一个是processNode,其值为当前节点的编号,另外一个是maxserailId,其值为起始事件单元中涉及的所有事件(实际上就是所有的起始事件)的serialId字段值中最大的一个,即maxserialId=MAX(serialId)。而在使用组内冗余的策略时:将上面的processNodeCode换为processGroupCode即可,在这种情况下,同一个节点组内的各个实例,模板是相同的。
部署卸载功能:负责部署和卸载业务处理模板。当用户发出部署指令时,使用上一功能得到的模板,依次为规则引擎集群当中的节点下发部署对应模板的指令,部署完毕后,在数据库中保存部署成功的节点信息,提示用户部署完成。当用户发出卸载指令时,则根据数据库中的记录,向对应节点下发卸载对应模板的指令,都卸载完毕后删除数据库中部署成功的信息,提示用户卸载完成。
分散负载模块:负责将规则处理的业务负载,分散到各个规则引擎节点或者节点组上。可以将规则中的事件序列的配置视为由若干个事件单元组成,每个事件单元接受若干类事件,都有一个起始状态、一个结束状态、从起始状态到结束状态的转移条件(可以为空),若一个事件单元位于事件序列配置中的首位,则其起始状态可以为空。序列中相邻的两个事件单元,前一个的结束状态与后一个的起始状态相同。事件单元的状态转移条件可以选择直接用字面量对事件信息进行过滤(直接过滤条件),也可以选择与位于其前面的事件单元中实际获得的事件信息进行过滤(引用过滤条件)。例如,事件序列要求a类传感器上报读数(第一个事件单元,也是起始单元,a为起始事件)之后,b类传感器也上报读数(第二个事件单元),要求b类传感器上报的读数要小于100(直接过滤条件),并且大于a类传感器上报的读数(引用过滤条件)。此外规则中还有对于事件是否连续发生(即是否允许两个事件单元之间是否可以穿插一些不符合事件序列配置的其他事件)和事件序列的匹配时长(即一次事件序列匹配从第一个事件单元达到结束条件开始,能存在多长时间内)的配置。
事件序列中的事件单元有多种类型,对其中可以作为起始单元的事件单元分别说明如下:
一元事件单元:一个满足转移条件的事件发生时,则匹配成功。
合取二元事件单元:两个满足各自转移条件的事件都发生时,此单元才匹配成功。
析取二元事件单元:两个满足各自转移条件的事件任一发生时,此单元就匹配成功。
非事件单元,共有5种变体:
普通非事件单元:指定时间段内,符合转移条件的事件不发生。
非事件追加和事件单元:在满足普通非事件单元的基础上,符合转移条件的追加事件也发生一次,这个单元才匹配成功。
非事件追加或事件单元:满足普通非事件单元要求,或者符合转移条件的追加事件发生一次时,这个单元都匹配成功。
非事件追加和非事件单元:如果满足普通非事件单元要求,并且符合转移条件的追加事件在对应时间段内也没有发生,则匹配成功。
非事件追加或非事件单元:如果满足普通非事件单元要求,或者符合转移条件的追加事件在对应时间段内没有发生,都匹配成功。
规则引擎系统处理的业务是规则,就是从无限长的事件序列中的各个位置开始对其中事件进行匹配,如果符合规则的要求,即匹配成功,规则触发。如果让不同的节点分别从不同的位置开始进行事件的匹配工作,则完成了分散负载。分散负载模块的核心思想如此,通过下面各章节中所述机制来指定由不同节点(或者节点组,下同)从事件序列中的不同起始事件开始来进行匹配,进行业务处理。
分散负载模块由多个分散负载实例组成,处于同一个进程中,一个分散负载实例,对应一个在部署中状态的规则。分散负载模块负责维持一个消费者,不同事件序列总线上的分散负载模块使用相同的消费组,消费由事件消息编码模块排序完成的事件序列,并将消费到的消息转换成内存对象,转发给同进程内的各个分散负载实例,由分散负载实例负责进行分散负载。根据起始单元、集群部署策略、匹配时长不同和处理要求,分为多种情况,下面分别说明其使用的机制。
机制1-4是普通一元事件单元或析取二元事件单元作为起始单元时的具体机制。
机制1,互为主备策略下以普通一元事件单元作为起始单元:
(1)获得规则所需事件类型列表L,获得起始事件单元U。
(2)获取规则引擎集群中的规则引擎节点个数n及每个节点的编号,初始化一个环形链表R,其初始长度为n,链表当中存放内容是规则引擎节点信息,这个信息包含节点的编码c、失败次数e(初始为0)和最近失败时间t(初始为空)。
(3)准备两个指针p1和p2指向环形链表中的元素,p1指向的元素是应该从当前起始事件开始进行事件序列匹配的规则引擎节点,p2指向的元素是实际上从上一个起始事件开始进行事件序列匹配的规则引擎节点,初始状态时都指向环形链表中的第一个元素。
(4)初始化变量T,其代表下次可能有恢复正常功能的规则引擎实例节点的时间,初始为空。另外需要一个队列Q,用来存放失败的规则引擎实例节点信息
(5)开始循环,每个分散负载实例接收从分散负载模块消费者发来的事件消息e,如果此事件e的类型不在事件类型列表L当中,则舍弃这条消息并重复本步骤,否则进入下一步骤。
(6)如果e的类型与起始事件单元U中要求的事件类型一致,则进入下一步骤,否则进入第(13)步。
(7)对事件消息添加字段processNodeCode,字段的值为指针p1当前指向的节点编码c,调用事件发送模块当中的报文发送功能(指定需要响应),将报文发送给每个部署中的规则引擎实例,开始待实例的响应。
(8)规则引擎实例收到消息后,发现报文当中的processNodeCode值与当前部署的业务处理模板中指定的值一致,则立即向事件发送模块当中的响应接收功能回报响应,响应中包括了报文中的serialId。无论是否发送,规则引擎实例都按照自己的规则处理逻辑继续处理。(实际上只有节点编号与报文中值相等时视为起始事件,不相等时只能作为非起始事件)
(9)由于每个规则引擎实例都有不同的编号,且发送的processNodeCode值仅和其中的一个编号相同,所以响应接收功能只会收到一个响应,但是如果当前这个规则引擎实例已经宕机或者是过于繁忙,就会收不到响应或不能按时收到响应;所以分散负载实例将调用事件发送模块的响应接收功能获取对应的serialId响应,待这个响应的时长为w(w取值应为2倍的RTT (Round Trip Time),这里根据我们实际上的应用,设置为2ms比较合适),如果收到了响应,则进入第(10)步,否则将指针p1向后移动一位并重复第(7)步。
(10)检查指针p2的指向是否与指针p1一致,如果一致则进入下一步;否则将指针p2当前的指向失败次数e加1,如果其失败次数e达到了f次(根据经验,f取值为3比较合理),则将其失败时间t设置为当前时间,并暂时将其从环形链表当中移除,并将移除的元素加入队列Q;如果当前全局变量T不为空,则将当前时间加上时间间隔g(g的取值略大于MTTR(Mean Time To Repair),根据经验MTTR为30秒,g的值设置为40秒),结果赋值给T,并将指针p2的指向向后移动一位,重复本步骤。
(11)如果当前T不为空,且当前时间大于T,则从队列Q中取出一个元素i1,并读取取出后的队头元素i2,将i1的失败次数e设置为0,失败时间t清空,并将此实例插入到链表中指针p1指向位置之后;如果i2不为空,则将其失败时间t加上g,赋值给T,如果i2为空,则将T的值清空。
(12)将p1指针向后移动一位,进入第(5)步。
(13)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(5)步。
机制2,组内冗余策略下以普通一元事件单元作为起始单元的:
(1)同机制1第(1)步。
(2)获取规则引擎集群中的规则引擎节点组个数m及每个节点组的编号,初始化一个数组A,其初始长度为m,数组当中存放内容是规则引擎节点组编码c。
(3)准备一个指针p指向数组A中的元素,p指向的元素是应该从当前起始事件开始进行事件序列匹配的规则引擎节点组,初始状态时指向数组A中的第一个元素。
(4)同机制1第(5)步。
(5)如果e的类型与起始事件单元U中要求的事件类型一致,则进入下一步骤,否则进入第(7)步。
(6)对事件消息添加字段processGroupCode,字段的值为指针p当前指向的节点组编码c,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例;将指针p的指向向后移动一位,进入第(4)步。
(7)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(4)步。
机制3,互为主备策略下以析取二元事件单元作为起始单元:在机制1基础上修改其中第(6)步为“如果e的类型与起始事件单元U中要求的两个事件类型之一相同,则进入下一步骤,否则进入第(13)步”。
机制4,组内冗余策略下以析取二元事件单元作为起始单元:在机制2基础上修改其中第(5)步为“如果e的类型与起始事件单元U中要求的两个事件类型之一相同,则进入下一步骤,否则进入第(7)步”。
机制5-16是合取二元事件单元作为起始单元时的具体机制。在此时,分为高可用性、高一致性1PC和高一致性2PC三种方案。先对高一致性方案中需要使用的一些子流程进行说明,高一致性的机制,都需要一个全局的队列,队列采用publish/subscribe模式。同时1PC方案还需要增加一个协调者的角色,协调者可以单独部署,也可以通过选举从多个分散负载实例中选择一个担任。协调者维持一个用于合并操作的本地队列,队列当中的元素是操作,操作分为如下2种:
【占用】操作:参数为消息的编号;返回值为“允许”和“拒绝”,“允许”代表此消息未被占用,此时需要截断此消息之前的全部消息,“拒绝”代表此消息已经被占用。
【转换】操作:参数为换成的状态和消息的具体信息;返回值为“允许”和“拒绝”,“允许”代表队列状态已经是此消息所属的状态或者队列为空,此时需要发送此消息并将消息加入全局队列;“拒绝”代表队列状态不是此消息所属的状态,且全局队列不为空。
使用【选举】流程确定协调者:当一个实例I尝试联系协调者但是没有收到响应时,这个实例就会尝试发起【选举】流程,要求成为新的协调者,并将当前的接收到的最后一个起始事件的serialId发送到其他实例。如果其他实例最后接收到的起始时间携带的serailId都小于I发送过来的值,则I成为新的协调者,如果其他实例有比I发送的值更大的起始事件,则I放弃成为协调者,接收其他实例发送的要求成为新的协调者的请求。
机制5,互为主备策略、高可用、规则不指定匹配时长时以合取二元事件作为起始单元:
(1)获得事件类型列表L和起始事件单元U所需两类事件A和B。
(2)同机制1第(2)步。
(3)准备四个指针pa1、pa2、pb1和pb2,指向环形链表中的元素,pa1指向的元素是应该从当前的A类起始事件开始进行事件序列匹配的规则引擎节点,pa2指向的元素是实际上从上一个A类起始事件开始进行事件序列匹配的规则引擎节点,pb1指向的元素是应该从当前的B类起始事件开始进行事件序列匹配的规则引擎节点,pb2指向的元素是实际上从上一个B类起始事件开始进行事件序列匹配的规则引擎节点,这四个指针初始状态时都指向环形链表中的第一个元素。
(4)同机制1第(4)步。
(5)同机制1第(5)步。
(6)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(13)步。
(7)对事件消息添加字段processNodeCode,字段的值取决于e的类型,若为A则为指针pa1当前指向的节点编码ca,若为B则为指针pb1当前指向的节点编码cb,调用事件发送模块当中的报文发送功能(指定需要响应),将报文发送给每个部署中的规则引擎实例,开始待实例的响应。
(8)同机制1第(8)步。
(9)由于每个规则引擎实例都有不同的编号,且发送的processNodeCode值仅和其中的一个编号相同,所以响应接收功能只会收到一个响应,所以分散负载实例将调用事件发送模块的响应接收功能获取对应的serialId响应,待这个响应的时长为w,如果收到了响应,则进入第(10)步,否则将指针向后移动一位(如果e的类型是A则移动指针pa1,否则移动pb1)并重复第(7)步。
(10)如果e的类型是A则检查指针pa2的指向是否与指针pa1一致,否则检查指针pb2的指向是否与指针pb1一致,如果一致则进入下一步;否则创建局部变量指针p(如果e的类型是A则这个指针p是pa2,否则是pb2),将指针p当前的指向失败次数e加1,如果其失败次数e达到了f次,则将其失败时间t设置为当前时间,并暂时将其从环形链表当中移除,并将移除的元素加入队列Q,同时检查所有4个指针,如果某个指针指向了要被移除的元素,则将这个指针向后移动一位;如果当前全局变量T不为空,则将当前时间加上时间间隔g,结果赋值给T,并将指针p的指向向后移动一位,重复本步骤。
(11)同机制1第(11)步。
(12)如果e的类型是A则将pa1指针向后移动一位,否则将pb1指针向后移动一位,进入第(5)步。
(13)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(5)步。
机制6,互为主备策略、1PC、规则不指定匹配时长时以合取二元事件作为起始单元:
(1)获得事件类型列表L和起始事件单元U所需两类事件A和B。
(2)同机制1第(2)步。
(3)准备指针p指向环形链表中的元素,被指向的元素是应该从当前的新起始事件开始进行事件序列匹配的规则引擎节点,指针初始状态时指向环形链表中的任意一个元素。
(4)同机制1第(5)步。
(5)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(12)步。
(6)假设e的类型是A,则尝试从全局队列当中取出一个事件o,如果能够取到则o的类型一定是B,此时进入下一步骤,否则取不到则进入第(10)步(若e的类型是B,则取出的o一定是A类)。
(7)向协调者发送【占用】操作请求,如果协调者返回“拒绝”,则放弃事件o并回到上一步骤;如果协调者返回“允许”,则进入下一步骤;如果协调者没有响应,则发起【选举】流程,如果本实例成为新的协调者,则也进入下一步骤,如果本实例没有成为新的协调者,则待时间w后(根据经验w取100ms比较合适),重复本步骤。
(8)对事件e的消息添加字段processNodeCode,值为事件o的processNodeCode值,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例。
(9)规则引擎实例收到消息后,发现报文当中的processNodeCode值与当前部署的业务处理模板中指定的值一致,则规则引擎实例会按照自己的规则处理逻辑继续处理,回到第(4)步。(实际上只有节点编号与报文中值相等时视为起始事件,不相等时只能作为非起始事件,此时所需的两个起始事件都被发送到了同一个规则引擎实例上)
(10)为事件e的消息添加字段processNodeCode,值为p指向元素的节点编号c,向协调者发送【转换】操作请求,如果协调者返回“拒绝”,则放弃事件o并回到第(6)步,如果协调者返回“允许”,则进入下一步骤。
(11)将p的位置向后移动一位,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,回到第(4)步。
(12)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(4)步。
机制7,互为主备策略、2PC、规则不指定匹配时长时以合取二元事件作为起始单元,假设部署中的数量是2n+1个:
(1)获得事件类型列表L和起始事件单元U所需两类事件A和B。
(2)同机制1第(2)步。
(3)同机制6第(3)步。
(4)初始化一个本地队列Q,长度为l(根据业务繁忙程度和实际处理效率,l一般取值在10左右),用来存放本实例最近l条成功占用的事件消息中的serialId(当此队列已满,而有新的事件消息需要入队时,则队头元素出队,队尾元素入队);启动一条线程,接收其他分散负载节点发送过来的【占用】请求,如果请求中消息的serialId不在队列Q中,则返回“允许”,否则返回“拒绝”。
(5)初始化一个变量V,其取值为A、B或者空,为A时代表本节点当前有未处理完成的A类起始事件,为B是代表本节点当前有未处理完成的B类起始事件,为空时代表当前没有未处理的A或B类事件;启动一条线程,接收其他分散负载节点发送过来的【转换】请求,如果V的值为空或者请求中携带的事件类型与变量V值相同,则返回“允许”,否则返回“拒绝”。
(6)同机制1第(5)步。
(7)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(14)步。
(8)假设e的类型是A,则尝试从全局队列当中取出一个事件o,如果能够取到则o的类型一定是B,此时进入下一步骤,否则取不到则进入第(12)步(若e的类型是B,则取出的o一定是A类)。
(9)向所有其他的分散负载实例发送【占用】操作请求,如果返回“拒绝”的实例个数达到了n个,则放弃事件o并回到上一步骤;如果返回“允许”的实例个数达到了n个,则进入下一步骤。
(10)同机制6第(8)步。
(11)规则引擎实例收到消息后,发现报文当中的processNodeCode值与当前部署的业务处理模板中指定的值一致,则规则引擎实例会按照自己的规则处理逻辑继续处理,回到第(6)步。
(12)为事件e的消息添加字段processNodeCode,值为p指向元素的节点编号c,向所有其他的分散负载实例发送【转换】操作请求,如果返回“拒绝”的实例个数达到了n个,则放弃事件o并回到第(8)步,如果返回“允许”的实例个数达到了n个,则进入下一步骤。
(13)将p的位置向后移动一位,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,回到第(6)步。
(14)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(6)步。
机制8,互为主备策略、高可用、规则指定匹配时长时以合取二元事件作为起始单元:
(1)获得事件类型列表L和起始事件单元U所需两类事件A和B;取得规则中配置的匹配时长D。
(2)同机制1第(2)步。
(3)同机制1第(3)步。
(4)初始化变量T,其代表下次可能有恢复正常功能的规则引擎实例节点的时间,初始为空;初始化一个队列Q,用来存放失败的规则引擎实例节点信息,初始为空;初始化一个队列M,用来存放由本分散负载实例发送给规则引擎实例的事件信息当中的发送时间sendTimestamp和处理节点编码processNodeCode。
(5)同机制1第(5)步。
(6)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(16)步。
(7)判断e的类型和队列M队头元素的类型是否相同(队列M为空则视为相同),如果相同则进入下一步,否则进入第(14)步。
(8)对事件消息添加字段processNodeCode,字段的值为指针p1当前指向的节点编码c,对事件消息添加字段sendTimestamp,值为当前时间戳,调用事件发送模块当中的报文发送功能(指定需要响应),将报文发送给每个部署中的规则引擎实例,开始待实例的响应。
(9)同机制1第(8)步。
(10)由于每个规则引擎实例都有不同的编号,且发送的processNodeCode值仅和其中的一个编号相同,所以响应接收功能只会收到一个响应,所以分散负载实例将调用事件发送模块的响应接收功能获取对应的serialId响应,待这个响应的时长为w,如果收到了响应,则将本次发送的事件报文放入队列M队尾并进入下一步骤,否则将指针p1向后移动一位并重复第(8)步。
(11)检查指针p1与p2的指向是否一致,如果一致则进入下一步;否则将指针p2当前的指向失败次数e加1,如果其失败次数e达到了f次,则将其失败时间t设置为当前时间,并暂时将其从环形链表当中移除,并将移除的元素加入队列Q;如果当前全局变量T不为空,则将当前时间加上时间间隔g,结果赋值给T,并将指针p2的指向向后移动一位,重复本步骤。
(12)同机制1第(11)步。
(13)将p1指针向后移动一位,进入第(7)步。
(14)从队列M中取出队头元素事件o,如果o为空则进入第(8)步,否则o出队并检查o中的sendTimestamp与当前时间的差值是否大于匹配时长D,如果大于则重复本步骤,如果不大于则进入下一步骤。
(15)对事件e的消息添加字段processNodeCode,值为o中的processNodeCode值,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,回到第(5)步。
(16)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(5)步。
机制9,互为主备策略、1PC、规则指定匹配时长时以合取二元事件作为起始单元:
(1)同机制8第(1)步。
(2)同机制1第(2)步。
(3)同机制6第(3)步。
(4)同机制1第(5)步。
(5)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(13)步。
(6)假设e的类型是A,则尝试从全局队列当中取出一个事件o,如果能够取到则o的类型一定是B,此时进入下一步骤,否则取不到则进入第(11)步(若e的类型是B,则取出的o一定是A类)。
(7)检查o中的sendTimestamp与当前时间的差值是否大于匹配时长D,如果大于则放弃o并回到第(6)步,如果不大于则进入下一步骤。
(8)向协调者发送【占用】操作请求,如果协调者返回“拒绝”,则放弃事件o并回到上一步骤;如果协调者返回“允许”,则进入下一步骤;如果协调者没有响应,则发起【选举】流程,如果本实例成为新的协调者,则也进入下一步骤,如果本实例没有成为新的协调者,则待w后,重复本步骤。
(9)同机制6第(8)步。
(10)规则引擎实例收到消息后,发现报文当中的processNodeCode值与当前部署的业务处理模板中指定的值一致,则规则引擎实例会按照自己的规则处理逻辑继续处理,回到第(4)步。
(11)为事件e的消息添加字段processNodeCode,值为p指向元素的节点编号c,并且为事件e的消息添加字段sendTimestamp,值为当前时间戳,向协调者发送【转换】操作请求,如果协调者返回“拒绝”,则放弃事件o并回到第(6)步,如果协调者返回“允许”,则进入下一步骤。
(12)将p的位置向后移动一位,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,回到第(4)步。
(13)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(4)步。
机制10,互为主备策略、2PC、规则指定匹配时长时以合取二元事件作为起始单元,假设部署中的数量是2n+1个:
(1)同机制8第(1)步。
(2)同机制1第(2)步。
(3)同机制6第(3)步。
(4)同机制7第(4)步。
(5)同机制7第(5)步。
(6)同机制1第(5)步。
(7)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(15)步。
(8)假设e的类型是A,则尝试从全局队列当中取出一个事件o,如果能够取到则o的类型一定是B,此时进入下一步骤,否则取不到则进入第(13)步(若e的类型是B,则取出的o一定是A类)。
(9)检查o中的sendTimestamp与当前时间的差值是否大于匹配时长D,如果大于则放弃o并回到第(8)步,如果不大于则进入下一步骤。
(10)同机制7第(9)步。
(11)同机制6第(8)步。
(12)规则引擎实例收到消息后,发现报文当中的processNodeCode值与当前部署的业务处理模板中指定的值一致,则规则引擎实例会按照自己的规则处理逻辑继续处理,回到第(6)步。
(13)为事件e的消息添加字段processNodeCode,值为p指向元素的节点编号c,向所有其他的分散负载实例发送【转换】操作请求,如果返回“拒绝”的实例个数达到了n个,则放弃事件o并回到第(8)步,如果返回“允许”的实例个数达到了n个,则进入下一步骤。
(14)将p的位置向后移动一位,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,回到第(6)步。
(15)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(6)步。
机制11,组内冗余策略、高可用、规则不指定匹配时长时以合取二元事件作为起始单元:
(1)同机制5第(1)步。
(2)获取规则引擎集群中的规则引擎节点组个数m及节点组的编号,初始化一个数组S,其初始长度为m,数组当中存放内容是规则引擎节点组编码c。
(3)准备两个指针p1和p2指向数组S中的元素,p1指向的元素是应该从当前的A类起始事件开始进行事件序列匹配的规则引擎节点组,p1指向的元素是应该从当前的B类起始事件开始进行事件序列匹配的规则引擎节点组,初始状态时都指向数组S中的第一个元素。
(4)同机制1第(5)步。
(5)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(7)步。
(6)创建局部变量p,若e为A类则p的取值为指针p1,若e为B类则p的取值为指针p2,对事件消息添加字段processGroupCode,字段的值使用p当前指向的节点编码c,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,发送完成后将p的指向向后移动一位(即将p1或者p2的指向向后移动一位),回到第(4)步。
(7)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,进入第(4)步。
机制12,组内冗余策略、1PC、规则不指定匹配时长时以合取二元事件作为起始单元:在机制6的基础上将其中所有的“processNodeCode”字段换为“processGroupCode”字段,将其中的“节点编码”换为“节点组编码”即可。
机制13,组内冗余策略、1PC、规则不指定匹配时长时以合取二元事件作为起始单元:在机制7的基础上将其中所有的“processNodeCode”字段换为“processGroupCode”字段,将其中的“节点编码”换为“节点组编码”即可。
机制14,组内冗余策略、高可用、规则指定匹配时长时以合取二元事件作为起始单元:
(1)同机制8第(1)步。
(2)同机制11第(2)步。
(3)同机制11第(3)步。
(4)初始化一个队列M,用来存放由本分散负载实例发送给规则引擎实例的事件信息当中的发送时间sendTimestamp和处理节点组编码processGroupCode。
(5)同机制1第(5)步。
(6)如果e的类型为A或者B两类事件之一,则进入下一步骤,否则进入第(11)步。
(7)判断e的类型和队列M队头元素的类型是否相同(队列M为空则视为相同),如果相同则进入下一步,否则进入第(9)步。
(8)先创建局部变量p,若e为A类则p的取值为指针p1,若e为B类则p的取值为指针p2,对事件消息添加字段processGroupCode,字段的值使用p当前指向的节点组编码c;然后为事件消息添加字段sendTimestamp,值为当前时间戳;最后调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,发送完成后将p的指向向后移动一位(即将p1或者p2的指向向后移动一位),并向队列M的队尾添加此事件消息,回到第(5)步。
(9)从队列M中取出队头元素事件o,如果o为空则进入第(8)步,否则o出队并检查o中的sendTimestamp与当前时间的差值是否大于匹配时长D,如果大于则重复本步骤,如果不大于则进入下一步骤。
(10)对事件e的消息添加字段processGroupCode,值为o中的processGroupCode值,调用事件发送模块当中的报文发送功能,将报文发送给每个部署中的规则引擎实例,回到第(5)步。
(11)调用事件发送模块当中的报文发送功能,向所有的规则引擎处理节点发送这个事件的报文,回到第(5)步。
机制15,组内冗余策略、1PC、规则指定匹配时长时以合取二元事件作为起始单元:在机制9的基础上,将其中所有的“processNodeCode”字段换为“processGroupCode”字段,将其中的“节点编码”换为“节点组编码”即可。
机制16,组内冗余策略、2PC、规则指定匹配时长时以合取二元事件作为起始单元:在机制10基础上,将其中所有的“processNodeCode”字段换为“processGroupCode”字段,将其中的“节点编码”换为“节点组编码”即可。
机制17用于当非事件单元各种变体作为起始单元时,此时必然有至少一类事件发生次数较少,此时可以尝试将其拆分为两个部分,第一个部分是规则要求的事件序列中从起始到第一个不是非事件单元的事件单元之前,称为起始部分,第二部分为剩余部分,其中剩余部分可以为空。若剩余部分不为空,则为剩余部分添加一个一元事件单元R放在剩余部分的首位,R接收的事件是起始部分的触发事件(R是一种逻辑上的事件,和数据库中存储的由事件类型配置功能配置的事件不同,其ID为-1,仅在这个规则当中使用),使用机制1和机制2完成水平扩展。对于起始部分,要求只在规则引擎集群中的一个节点上部署,使用以下机制:
(1)在Redis中创建一个键值对K,key为startPart+ serailId+规则id,值为0。开启一条线程,负责消费kafka中名为startPart+规则id的topic中的数据
(2)使用规则分析功能分析规则的事件序列配置,获得起始部分包含的事件单元列表W,并获得W中各个单元接收事件类型列表L。
(3)同机制1第(5)步。
(4)调用事件发送模块当中的报文发送功能(指定目标节点),将报文发送给部署这个起始部分的规则引擎节点,发送结束后回到第(3)步。
(4)当这个规则引擎节点判断W中所有的事件单元都已经依次满足了转移条件,此起始部分的规则将触发,会把触发消息发送到kafka中名为startPart+规则id的topic中。
(5)分散负载实例在收到一个逻辑事件R时,读取键值对K的值v,为逻辑事件R添加字段serialId,值为v,将v加1后用此新值更新键值对K。调用事件发送模块中的报文发送功能,向所有的规则引擎实例发送这条报文。回到第(3)步。
事件发送模块:负责事件序列总线与规则引擎集群中各个节点之间的通信,包括将报文发送给各个规则引擎节点,与从各个规则引擎节点接收回送的响应。主要包含两个功能,“报文发送功能”和“响应接收功能”,这两个功能通过一个散列桶M进行沟通。图8展示的是事件发送模块的结构和流程,即图3中事件发送模块的详细展开。
报文发送功能:负责将事件的报文从事件序列总线发送到规则引擎集群当中的规则引擎实例,此功能的详情如下:
【调用者】:分散负载模块当中的各个分散负载实例;
【入参1】:事件报文,必须传入,在得到此事件报文时,为报文添加字段busCode,值为总线编号;
【入参2】:是否需要响应,可以为空,为空时代表不需要响应;
【入参3】:指定的规则引擎节点编号,可以为空,不为空时代表事件报文只发送到这个节点上;
【效果】:如果不需要响应且节点编号为空,则通过kafka中名为eventSequence+规则id的topic,将消息进行广播;如果不需要响应且节点编号不为空,则通过kafka中名为eventSequence+节点(组)编码+规则id的topic,单独发送给一个节点;如果需要响应,在执行上面的基础上,另外还要取出事件报文中的serialId,向散列桶M中加入一个键值对,key为serialId字段的值,value为一个二元组,二元组由当前时间戳和状态(初始为false)组成。
响应接收功能:开启一条主线程E,每2秒扫描散列桶中所有键值对,如果其value的二元组当中的时间戳与当前时间相比超过2秒的,则从M中删除这个键值对。开启一条主线程R,接收本事件序列中间件内各个分散负载实例询问是否有响应的请求,如果M当中当前有此键,并且其value二元组中状态为true,则返回已收到响应,否则返回未收到响应。开启多条线程,接收kafka中所有topic名为nodeResponse+规则id+总线编号格式的消息,获取接收到的消息中的serialId字段,如果在M中有此键,则更新其value二元组中状态为true。
规则输出总线:当使用组内冗余策略时,仅负责规则输出的合并工作,当使用互为主备策略时,还需要负责合并转移负载的纠错功能。规则输出总线可以部署多个,一个规则输出总线负责若干个规则的输出去重任务,不同的规则输出总线负责去重的规则不会有重叠。规则输出总线中包含“重复触发合并模块”和“处理结果发送模块”,图9是规则输出总线的结构图和流程,即图1中规则输出总线的展开。
重复触发合并模块:根据选用的集群扩展策略的不同,分别采用下面两个流程,流程1是互为主备策略下的:
(1)创建一个变量M,初始化为0。
(2)启动一条线程间隔性的消费kafka中名为ruleOutput+规则id的topic当中的消息,每隔1秒接收一批消息,如果没有接收到任何消息重复本步骤,否则进入下一步骤。
(3)初始化一个列表L,存放这批消息当中出现的maxserialId。
(4)遍历这批消息,取出每个消息中的maxserialId字段值v,如果v小于M或者已经存在于列表L中则放弃这条消息,否则下一步。
(5)用v的值替换M的值,将v放入列表L当中,并且调用处理结果发送模块,将消息发送到下游业务系统,然后继续遍历这批消息,直到这批消息完全遍历结束后,回到第(2)步。
流程2是组内冗余策略下的,设节点组中实例个数为2n-1:
(1)创建一个散列桶M,初始化为空,这个散列桶的key为最大起始事件编号,value是一个二元组,二元组中包含时间戳和收到次数。
(2)启动一条线程,每隔一段时间(取值应为2-10倍的RTT,根据经验这里取2秒比较合适),扫描一遍散列桶中的value,如果发现value当中的时间戳与当前时间间隔超过2秒,则删除这个键值对。
(3)启动一条线程消费kafka中名为ruleOutput+规则id的topic当中的消息,如果没有接收到消息重复本步骤,否则进入下一步骤。
(4)取出每个消息中的maxserialId字段值k,如果散列桶M中不包含k这个键,则向M中添加k这个key,value的二元组为当前时间戳,收到次数为1;如果散列桶M中已经包含了k这个键,则将对应的value二元组中收到次数加1;然后进入下一步。
(5)检查当前的value二元组中的收到次数,如果已大于n,则说明半数以上的组内节点都认为应该触发这个规则,此时将键值对删除,并调用处理结果发送模块,将消息发送到下游业务系统,回到第(3)步;如果不大于n,则直接回到第(3)步。
处理结果发送模块:负责将合并重复触发后得到的规则输出发送到下游业务系统当中,供下游业务系统消费并处理,其调用者是规则输出总线的重复触发合并模块,调用时会携带要输出到下游业务系统的结果和此规则的id。在本模块接收到一次调用时,便将此规则的id作为添加到结果报文的ruleId字段当中。本模块支持主流的消息中间件,通过向其中的消息队列向外传输的方式发送该处理过的结果。
上述技术方案仅体现了本发明技术方案的优选技术方案,本技术领域的技术人员对其中某些部分所可能做出的一些变动均体现了本发明的原理,属于本发明的保护范围之内。
Claims (9)
1.一种使规则引擎实例进行水平扩展的控制系统,其特征在于,包括上游事件来源、下游业务系统、事件序列总线组、时间同步模块、规则引擎集群以及规则输出总线组;
所述上游事件来源是指其业务处理结果与这个处理结果对应的限定条件一起得到的任何业务系统,为规则引擎系统的所有业务提供业务处理的事件;
所述下游业务系统是指使用规则引擎处理结果进行下一步的业务处理的系统;
所述时间同步模块,所述时间同步模块将所有的总线、模块、实例的本地时间进行同步,保证系统内时间一致。
2.根据权利要求1所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述规则引擎集群单元由若干个规则引擎实例组成,各个实例可以以单独进程模式或者镜像模式进行部署,各个实例之间无状态。
3.根据权利要求1所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述事件序列总线组由多个事件序列总线组成,共同负责为规则引擎集群中实例集群内的各个节点或者节点组提供事件序列,每个事件序列总线由事件接收模块、事件消息编码模块、规则配置与分析模块、分散负载模块(分散负载模块中包含多个分散负载实例)和事件发送模块构成。
4.根据权利要求1所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述规则引擎集群内包含实例编码模块和实例集群,其中实例集群可以选择两种策略:当选择互为主备策略时,实例集群内包含多个规则引擎节点;当选择组内冗余策略时,实例集群内包含多个规则引擎节点组。
5.根据权利要求1所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述规则输出总线组由多个规则输出总线组成,共同负责将规则引擎集群得到的处理结果进行去重合并与发送;每个规则输出总线当中包含重复触发合并模块与处理结果发送模块;重复触发合并模块中包含多个去重任务,每个任务负责对一个规则进行去重;处理结果发送模块负责将去重合并后的处理结果发送到下游业务系统当中。
6.根据权利要求4所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述互为主备的集群部署策略:所有规则引擎实例之间构成互为主备关系,即如果一个实例失效,由集群内另外一个实例接替失效实例进行一次业务处理。
7.根据权利要求1所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述组内冗余的集群部署策略:所有的实例从逻辑上分为若干个组,每个组内的实例数量为奇数个,组内各个实例都执行完全相同的业务,若某个节点失效,不会影响组内其他节点,最终一个业务的处理结果以组内节点的大多数节点达成一致为原则。
8.根据权利要求7所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述规则引擎集群当选择互为主备策略时,每个实例都是集群内的一个节点,而在选择组内冗余策略时,若干个实例一起构成了集群内的一个节点组。
9.根据权利要求7所述的一种使规则引擎实例进行水平扩展的控制系统,其特征在于,所述实例编码模块负责对上节中所说的规则引擎实例集群中的实例进行编码,在系统当中通过这个编码来代表某个实例,实例的当前的工作状态、业务处理情况,及处理结果。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211055432.3A CN115357413A (zh) | 2022-08-31 | 2022-08-31 | 一种使规则引擎实例进行水平扩展的控制系统 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211055432.3A CN115357413A (zh) | 2022-08-31 | 2022-08-31 | 一种使规则引擎实例进行水平扩展的控制系统 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115357413A true CN115357413A (zh) | 2022-11-18 |
Family
ID=84004308
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202211055432.3A Pending CN115357413A (zh) | 2022-08-31 | 2022-08-31 | 一种使规则引擎实例进行水平扩展的控制系统 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115357413A (zh) |
-
2022
- 2022-08-31 CN CN202211055432.3A patent/CN115357413A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN105630589A (zh) | 分布式流程调度系统及流程调度、执行方法 | |
CN111209084B (zh) | 一种faas分布式计算方法和装置 | |
CN113760513B (zh) | 一种分布式任务调度方法、装置、设备和介质 | |
CN109766194B (zh) | 基于消息的低耦合计划任务组件的实现方法及其系统 | |
CN104092719A (zh) | 文件传输方法、装置及分布式集群文件系统 | |
CN111984274B (zh) | 一种一键自动化部署etcd集群的方法及装置 | |
CN114153580A (zh) | 一种跨多集群的工作调度方法及装置 | |
CN112667383B (zh) | 一种任务执行及调度方法、系统、装置、计算设备及介质 | |
CN108829545B (zh) | 一种实现分布式数据库备份的方法 | |
CN109560903B (zh) | 一种完全容灾的车载指挥通信系统 | |
JP2740105B2 (ja) | 分散データベース制御方法 | |
CN110647570A (zh) | 数据处理方法、装置以及电子设备 | |
CN112433830A (zh) | 一种基于ZooKeeper的分布式任务调度方法、系统及存储介质 | |
CN115357413A (zh) | 一种使规则引擎实例进行水平扩展的控制系统 | |
CN114584452A (zh) | 处理故障的方法、装置及系统 | |
CN111158930A (zh) | 一种基于Redis的高并发延时任务系统和处理方法 | |
CN113312316B (zh) | 数据处理方法及装置 | |
CN114531479B (zh) | 一种基于mqtt的通用数据采集系统 | |
CN114448995A (zh) | 基于raft选主策略的分布式计算方法 | |
CN115168434A (zh) | 一种共享存储集群数据库的数据同步方法及设备 | |
CN114416717A (zh) | 一种数据处理方法及架构 | |
CN114116178A (zh) | 集群框架任务管理方法以及相关装置 | |
CN113032131B (zh) | 基于Redis的分布式定时调度系统和方法 | |
CN112187542A (zh) | 数据通信的集群方法及系统 | |
CN111522805A (zh) | 分布式批量数据清理方法及系统 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |