分布式规则引擎框架的设计

news2024/11/24 12:34:12

MirAIe 规则引擎是一个可扩展且可扩展的规则引擎框架,允许用户对多个活动进行分组和自动化。

        过去几年,在开发MirAIe 物联网平台时,我们意识到需要一个可扩展、可扩展的规则引擎框架。规则引擎使您能够对各种操作进行分组、管理和自动化,并可用于各种应用程序,例如家庭自动化、欺诈检测、风险管理和工作流程自动化。在松下,我们参与了移动、工业 4.0、楼宇管理和家庭自动化领域的多项举措。因此,该框架必须能够适应各种应用程序。在本文中,我将描述我们的规则引擎框架的高级设计。

规则剖析

        规则本质上允许用户对大量任务进行分组和自动化。用户生成规则的示例包括,只要室温升至 27 度以上,就打开卧室空调;每天晚上 6 点打开办公室大厅的一组灯;当装配线中的机器效率低于以下时通知您80%,或者当电池电量低于 30% 时向您的电动汽车发送推送通知,并且在附近发现有空位的充电站。

 

        规则具有指定何时激活规则的触发条件。触发可能取决于用户的位置、传感器的状况、特定时刻、外部天气条件或任何其他因素。可以使用一个或多个逻辑运算符来耦合多个触发器,这些逻辑运算符一起指定规则的触发条件。

        规则还具有在满足这些触发条件时激活的一个或多个操作。操作可能像打开灯一样简单,也可能像创建报告并将其作为附件发送给多个用户一样复杂。

设计注意事项

        规则触发条件可能取决于多个输入源。数据源可以是内部的,例如安装在实验室中的传感器,每隔几秒发送一次周期性状态,也可以是外部的,例如天气数据,需要每天检索和存储一次,因为数据不会经常更改。挑战在于吸收多个输入源以创建单个值并确定是否应激活规则。

        由于我们的框架必须支持广泛的应用,我们决定重点关注两个基本设计原则。第一个原则是架构必须可扩展以支持各种输入触发和输出操作。对于家庭自动化用例,最常见的触发因素可能取决于时间、设备状态或外部天气条件。而对于我们的智能工厂用例,触发器可能是用户活动或随时间收集的聚合数据,例如机器效率。其想法是确保可以添加新的触发器类型,而无需对架构进行太多更改。同样,规则操作也是可扩展的。常见操作可以是调用 API、发送通知或创建任务并将其推送到任务队列。 

        我们对此设计的第二个指导原则是优先考虑灵活性,允许每个组件独立扩展。灵活的系统可以适应不断变化的需求,而无需扩展整个系统,从而提高弹性和成本效率。例如,如果晚上6点需要触发大量规则,系统只需适当扩展定时器触发服务和规则执行服务,而其他服务则继续按原有规模运行。通过提供这种灵活性,系统可以高效且有效地满足不同的需求。

规则引擎组件

        为了实现可扩展性,我们解耦了规则触发服务、规则处理引擎和规则执行服务。规则触发服务是微服务的集合,每个微服务能够处理特定类型的规则触发逻辑。规则引擎根据规则定义组合各种触发状态,以确定是否应触发规则。最后,规则执行服务是特定于应用程序的规则执行逻辑,用于执行规则中指定的预期操作。每个组件都是独立开发的。它们实现了定义良好的接口并且可以独立扩展。

 

规则触发服务

        规则触发服务实现逻辑以确定何时应触发规则。它是微服务的集合,每个微服务都能够处理非常特定类型的触发器。例如,时间点激活和基于持续时间的触发器的逻辑由定时器触发器的微服务处理。同样,不同的服务处理设备状态的触发器或基于天气的触发器。 

        根据规则定义中的规则触发条件,规则在首次创建时将其自身注册到一个或多个规则触发服务。每个触发器服务提供三个主要 API 来注册、更新和取消注册规则。注册触发器的实际有效负载可能因服务而异,但是,规则创建/更新 API 的设计方式使得规则管理服务可以快速识别触发器类型并将解析和解释触发条件委托给相应的触发器服务。各个触发器类型的端点可以作为配置或环境变量的一部分进行共享,也可以使用标准服务发现模式在运行时发现它们。

        每种触发器类型都有不同的激活服务逻辑。触发器可以从一个或多个输入源捕获数据,对其进行处理,必要时对其进行缓存,并在决定是否应触发规则时发出事件。当特定规则满足触发条件时,规则触发服务会发出布尔值 true,否则会发出 false。 

         规则可以包括一个或多个触发器,其中每个触发器都建立一个特定条件,必须满足该条件才能执行规则。例如,考虑每天下午 6 点或当环境照明水平低于 100 勒克斯时打开客厅灯的规则。该规则使用 OR 逻辑组合两个条件,第一个是基于时间的触发器,第二个是设备(ALS 传感器)状态触发器。还可以通过多个触发器和逻辑运算符的组合来创建更复杂的规则。 

 

        为了管理每个触发器的状态,使用了持久缓存,该缓存由相应的触发器服务更新。这确保了规则处理引擎始终可以使用最新的触发器状态,从而允许其评估条件并调用适当的操作。上图中,红色触发状态表示当前触发条件不满足,绿色状态表示触发条件已满足。一旦规则的触发状态发生变化,相应的触发服务会将规则id添加到队列中进行处理,随后由规则处理引擎消费。 

        每个规则触发服务都被设计为可水平扩展,并且可以根据注册规则的数量独立于其他系统组件进行扩展。这种解耦还允许每个触发器的激活逻辑随着应用程序的发展而独立发展。此外,可以以最小的更改将新的触发器类型添加到系统中。

规则处理引擎

        规则处理引擎从待处理规则队列中处理规则,并根据触发状态执行规则。如果触发逻辑是一个或多个规则触发器的组合,则处理引擎根据规则定义中指定的触发逻辑组合每个输入触发器的状态,以计算最终的布尔值。一旦它确定必须触发该规则,它就会调用规则执行服务来执行该规则。

        触发状态大致有两类。时间点触发仅在触发状态发生变化时才有效,例如下午六点激活规则或设备状态变化触发(例如空调打开时关闭风扇)。如果还满足所有其他触发条件,则应在事件发生后立即激活此类规则。规则处理引擎在处理完规则后立即重置此类触发器的值。

         第二类触发器代表实体在较长时间内的持久状态。例如,考虑这样一种场景:如果在下午 6 点到早上 6 点之间检测到运动,则应打开门廊灯。计时器触发服务会在下午 6 点将触发值设置为 true,然后在上午 6 点将其设置为 false。这些状态不会由规则处理引擎重置,并且保持不变,直到由触发器服务显式修改。这使得系统能够维护实体的持久状态并根据其持续状态做出决策。

 

规则执行服务

        规则执行服务可以调用 HTTP API、发送 MQTT 消息或触发推送通知来执行规则。规则可以执行的操作列表是特定于应用程序的并且是可扩展的。与规则触发服务一样,规则操作服务与核心规则引擎解耦,并且可独立扩展。 

 

        将规则执行服务与多个规则操作服务解耦的一种方法是使用消息队列,例如 Kafka。根据操作类型,规则执行服务可以将规则操作发布到单独的 Kafka 主题,一组消费者可以使用这些主题并执行相关操作。规则操作有效负载可以特定于操作类型,并作为规则定义的一部分捕获并按原样传递到任务队列。

扩展触发服务

        规则触发服务可以是有状态的,因此扩展它们可能是一个挑战。没有通用的方法来扩展所有触发器服务,因为它们的底层实现根据触发器类型和它们可能依赖的外部服务而变化。在本节中,我将解释用于两种重要触发器类型的缩放方法。

设备状态触发器

        为了向设备状态触发服务注册规则,规则管理服务将提供设备标识符、设备属性及其相应的阈值。设备状态触发服务会将这些存储在共享缓存(例如 Redis)中,并确保仅使用设备 ID 即可访问它们。

         在给定的示例中,有关设备状态变化的通知通过 MQTT 协议发送,然后添加到 Kafka 消息队列中。负责设备状态的 Kafka 消费者接收并处理每个传入事件。它检查规则触发器缓存以确定是否有任何规则与设备关联。根据此信息,消费者更新相应的触发器状态缓存,反映该设备触发器的当前状态。这种机制确保触发状态缓存与最新的设备状态变化保持同步,从而使系统能够根据最新的信息准确地评估规则。

        我们所有的服务都是容器化的,并在 Kubernetes 集群中运行。设备状态触发服务是标准API服务,通过应用程序负载均衡和自动伸缩组进行扩展。设备状态使用者组根据传入设备状态更改事件的速率进行扩展。Kubernetes 事件驱动自动缩放 (KEDA)可以根据需要处理的事件数量来驱动设备状态使用者的缩放。此外,还有一些工具可以预测 Kafka 工作负载,可以用来更迅速地扩展消费者,从而提高性能。

定时器触发

        定时器触发服务处理时间点触发和持续时间触发。触发请求有效负载可以像一天中的特定时间一样简单,也可以像Unix Cron 作业的规范一样详细。该服务不需要在内存中保存所有已注册的规则请求,因为规则可能几天或几个月都不会触发。相反,一旦它收到规则注册请求,它就会计算下一次应该运行该规则的时间,并将规则详细信息以及下一次运行时间存储在数据库中。
        该服务会定期以固定的时间间隔获取后续时间窗口中需要激活的所有规则并将其拉入内存。这可以通过过滤规则的下一个运行时间字段来完成。一旦确定了需要运行的所有规则,该服务就会按触发时间对规则进行排序,并生成一个或多个 Kubernetes Pod 来处理这些规则。每个 Pod 只会被分配规则的一个子集。可以通过 Zookeeper 或 Kubernetes自定义资源定义(CRD)共享分配给不同 Pod 的规则。

 

        Kubernetes CRD 可用于通过定义代表特定任务的自定义资源来共享数据并在多个 Pod 之间分配工作。定时器触发服务通过将下一个时间窗口中需要处理的所有规则划分为单独的任务并将它们存储在 CRD 中来使用此功能。随后创建多个工作单元并分配特定任务。然后,每个 Pod 处理规则并相应地更新触发器状态缓存。 

可维护性和可扩展性

        规则管理服务和规则执行服务是无状态服务,逻辑相当简单。规则管理提供用于规则创建、更新和删除的标准API。规则执行服务独立工作以执行规则操作,主要调用特定于应用程序的操作。

        规则管理服务和触发服务之间的通信可以异步进行,从而无需服务发现。例如,每个触发器服务都可以在 Kafka 消息代理中拥有其专用队列。规则管理服务可以根据触发类型将触发请求添加到相应的队列中,供触发类型的Kafka消费者(触发服务)处理来消费。

        添加对新触发器类型和新操作类型的支持很简单,因为所有关键组件都是相互解耦的。规则管理服务具有基于插件的设计,其中为每个支持的触发器类型和操作类型添加插件,以验证规则定义中相应的触发器和操作有效负载。规则触发器和操作类型名称可以转换为相应的 Kafka 队列名称,用于规则管理服务和触发器服务之间以及规则处理服务和执行服务之间的通信。

可以在多个级别上测试系统。通过单元测试覆盖各个服务并专注于特定功能相对容易。为了促进分布式环境中的轻松调试和故障排除,必须遵守分布式日志记录和跟踪的最佳实践。正确实施的日志记录和跟踪机制将使我们能够跟踪不同服务之间的请求流,有效地识别问题并诊断问题。遵循这些最佳实践可确保更好地了解系统行为并简化调试过程。

可靠性

        让我们首先确定可能出现的潜在挑战。重要的是要承认系统内的任何服务都可能会意外停机,系统负载的增长速度可能快于其有效扩展的能力,并且某些服务或基础设施组件可能会遇到暂时不可用的情况。 

        使用 Kafka 进行通信有助于实现多个级别的可靠性。Kafka 提供有助于消息传递和消费可靠性的功能,包括消息持久性、强大的持久性保证、容错复制、消费者组之间的负载分配以及至少一种传递语义。

        最直接的可靠性案例涉及触发服务。对于设备状态触发,Kafka配置为保证至少一次投递,从而保证状态变化事件不会丢失。然而,实现定时器触发服务的可靠性需要额外的步骤。在这里,重要的是要避免让任何单个工作人员因需要同时处理的大量事件而不堪重负。  

        我们的方法是按时间顺序排列下一个时间窗口中要处理的规则列表,并以循环方式在工作人员服务之间分发它们。此外,worker pod 的数量与时间窗口内的计时器任务数量以及任何给定时间要执行的最大任务数量成正比。这确保了有足够数量的工作节点可同时处理潜在的大量计时器任务。此外,将工作单元配置为在崩溃时自动重新启动也是有益的,使其能够恢复并完成分配的任务,而无需手动干预。  

        此外,Kubernetes 还具有为每个服务定义资源限制和最低要求的优势。这包括指定服务可以利用的最大 CPU 或 RAM 资源量以及成功启动所需的最少资源。借助 Kubernetes,可以减轻对“吵闹邻居”问题(即一个 Pod 的资源密集型行为影响同一集群节点上的其他 Pod)等问题的担忧。Kubernetes 提供隔离和资源管理能力,有助于维护整个系统的稳定性和可靠性。 

概括

        MirAIe 规则引擎是一个可扩展且可扩展的规则引擎框架,允许用户对多个活动进行分组和自动化。该框架支持各种内部或外部触发器,并侧重于两个设计原则:可扩展性和灵活性。该架构必须可扩展,以支持各种输入触发器和输出操作,从而允许在不进行太多更改的情况下添加新类型。该系统还优先考虑灵活性,以实现每个组件的独立扩展,从而提高弹性和成本效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git【潦草学习】

初始配置git 查询版本号 初次使用git前配置用户名与邮箱地址 git config --global user.name "your name" git config --global user.email "your email" git config -l 发现最后两行多出了用户名和邮箱,说明配置成功

对指针变量引用以及自定义类型引用的认识

#include <iostream> using namespace std; #include <iomanip>typedef int G[10]; //自定义类型void test(int* p); // void test_0(int &p); //表明p是一个int型变量的别名 void test_1(G &pG); //表明pG是一个G类型变量的别名 void test_2(int*…

PMP备考心得分享

备考PMP考试是一段充满挑战和成长的旅程。参加某机构的PMP培训课程&#xff0c;有国内PMP考培资深讲师的授课&#xff0c;以及班主任的周期监督管理&#xff0c;无疑是我备考成功的重要支撑。在这个过程中&#xff0c;我积累了许多宝贵的经验和心得&#xff0c;现在将它们分享给…

GPT-5出世,需5万张H100!英伟达GPU陷短缺风暴

随着人工智能技术的不断突破&#xff0c;自然语言处理领域也掀起了一波又一波的革命。从GPT-3.5的惊艳登场&#xff0c;到紧随其后的GPT-4的惊世震人&#xff0c;人们仿佛置身于科幻电影中&#xff0c;亲历了一场场技术的奇迹。然而&#xff0c;这场奇迹背后却逐渐显现出一道不…

解决问题:ModuleNotFoundError: No module named ‘mmcv._ext‘,及安装mmcv-full的详细教程

解决问题**ModuleNotFoundError: No module named ‘mmcv._ext’**之前得先搞懂mmcv和mmcv-full的关系。 mmcv 和 mmcv-full 都是针对 PyTorch 的计算机视觉基础库,两者的主要区别是: mmcv 包含了 mmcv 的核心组件,例如运行器、回调函数、可视化工具等,打包体积较小。mmcv-fu…

K8S系列文章之 自动化运维利器 Fabric

Fabric 主要用在应用部署与系统管理等任务的自动化&#xff0c;简单轻量级&#xff0c;提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中&#xff0c;它混杂了本地及远程两类功能&#xff1b;但自 Fabric 2.x 版本起&#xff0c;它分离出了独立的 Invoke 库&#xff0c;来处理…

bigemap国土管理行业应用

由于国营企业单位&#xff0c;管理土地&#xff0c;必须要有这样的软件套图 客户之前用的谷歌&#xff0c;后来不能访问了&#xff0c;通过其他途径搜索到我们 客户使用软件一般都用于套坐标以及空间规划图&#xff0c;方便于项目选址和居民建房报建在卫星图上找到用地范围&am…

远程调试MySQL内核

1 vscode 需要安装remote-ssh插件 安装成功后&#xff0c;登录&#xff1a; 默认远程服务器的登录 ssh rootip注意&#xff0c;Linux需要设置root远程登录&#xff1b; 2 安装debug扩展 C\C extemsion Pack C\Cgdb debugger beyond用于进程attach 3 设置Attach进程 {// …

MyBatis源码剖析之Mapper代理方式细节

MyBatis是一个流行的Java持久层框架&#xff0c;它提供了多种方式来执行数据库操作&#xff0c;其中之一就是通过Mapper代理方式。通过Mapper代理方式&#xff0c;开发者可以编写接口&#xff0c;然后MyBatis会动态地生成接口的实现类&#xff0c;从而避免了繁琐的SQL映射配置。…

前端主题切换方案——CSS变量

前言 主题切换是前端开发中老生常谈的问题&#xff0c;本文将介绍主流的前端主题切换实现方案——CSS变量 CSS变量 简介 编写CSS样式时&#xff0c;为了避免代码冗余&#xff0c;降低维护成本&#xff0c;一些CSS预编译工具&#xff08;Sass/Less/Stylus&#xff09;等都支…

Java基础入门篇——Java注释、关键字和标识符(二)

目录 一、注释 1.1注释介绍 1.2单行注释 1.3多行注释 1.4文档注释 1.5javadoc注释标签语法 二、关键字 三、字面量 3.1什么是标识符&#xff1f; 3.2标识符命名规则 四、总结 一、注释 在Java中&#xff0c;注释是用来向代码添加解释、说明和文档信息的文本。Java…

网工这行最大的内卷,就是养了一批“HCIE”

下午好&#xff0c;我是老杨。 这段时间&#xff0c;我个人工作上的事儿挺多&#xff0c;一直在处理。 手底下的一个重要项目组&#xff0c;想招个新人&#xff0c;面了几批都不满意&#xff0c;难搞。 前两天刚定下人选&#xff0c;现下和你聊上几句。 上回说过&#xff0…

Killing LeetCode [82] 删除排序链表中的重复元素 II

Description 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 Intro Ref Link&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/ Difficulty&#xff1a;Medium T…

怎么在树莓派环境上搭建web网站,并发布到外网可访问,今天教给大家

怎么在树莓派上搭建web网站&#xff0c;并发布到外网可访问&#xff1f; 文章目录 怎么在树莓派上搭建web网站&#xff0c;并发布到外网可访问&#xff1f;概述使用 Raspberry Pi Imager 安装 Raspberry Pi OS测试 web 站点安装静态样例站点 将web站点发布到公网安装 Cpolarcpo…

OpenStack监控工具

OpenStack是一个开源的云计算管理平台项目&#xff0c;是一系列软件开源项目的组合。由NASA和Rackspace合作研发并发起&#xff0c;以Apache许可证&#xff08;Apache软件基金会发布的一个自由软件许可证&#xff09;授权。 OpenStack为私有云和公有云提供可扩展的弹性的云计算…

mac电脑三维建模 Rhino 7中文 7.32

Rhino 7特别功能介绍 • 不受约束的自由形式 3D 建模工具&#xff0c;如仅在成本高出 20 到 50 倍的产品中发现的工具。为您可以想象的任何形状建模。 • 设计、原型、工程、分析和制造从飞机到珠宝的任何东西所需的准确性。 • 与您的所有其他设计、绘图、CAM、工程、分析、…

git使用(常见用法)

一.下载git git官方下载跳转 安装简单,有手就行 二. git的简单使用 1. 连接远程仓库 #初始化 git init #配置账户 git config --global user.name “输入你的用户名” git config --global user.email “输入你的邮箱” git config --list #--q退出 #配置验证邮箱 ssh-key…

vue2 引用swiper

参考引用 &#xff1a; vue使用swiper实现轮播图一页多张图片效果_swiper多张图片排列的轮播_空空的博客-CSDN博客 vue2 使用swiper_vue2使用swiper__NIXIAKF的博客-CSDN博客 常见的属性&#xff1a;Swiper 中常见的属性以及方法_swiper-wrapper_超勇的.的博客-CSDN博客 1、…

8月16日起!亚马逊新商品上架需更新产品类型的274个属性!

亚马逊美国站发布公告称为了帮助买家更轻松地搜索产品&#xff0c;改善买家的购买决策提高卖家的销量&#xff0c;8月16日起受影响的200种产品类型的274个属性在上架前需更新属性&#xff0c;以下是公告内容&#xff1a; 自2023年8月16日起&#xff0c;200种产品类型的274个属…

想在金融界拥有一席之地吗—社科院杜兰大学金融管理硕士助你圆梦

追求高学历是为了什么&#xff1f;一纸证书吗&#xff1f;显然并非如此&#xff0c;只有读过研的人才有话语权。在上升一个平台后&#xff0c;你必然会发现&#xff0c;更高学历得到的不止是一张文凭。而是更大的平台、更广阔的视野、更包容的环境&#xff0c;更多样的文化。最…