如何设计一套规则引擎系统

时间:2024-01-26 22:14:26

很早之前就想写一篇关于「规则引擎」的文章,但是一直苦于没有时间。刚好最近给团队小伙伴梳理了我设计的引擎的使用和原理,正好借此机会在此写下我们的心得。
「规则引擎」系统一般而言,在风控中使用较多,但是经过调研,我们发现,其实在业务系统中,对于规则引擎系统的渴求度更大,甚至于,我在脉脉上都看到好几个人在咨询业务规则引擎系统应该如何设计和接入。

首先来聊一下痛点。为什么对于规则引擎系统的渴求度这么大?

缺点

业务条件繁杂

试想一下,或者说正是你所经历的,在我们的业务逻辑中,有很多很多很多的业务条件判断,而这些业务条件的修改往往又较为频繁,如果你的项目部署还比较耗时,那么“开发五分钟,部署一小时”的场景又会浮现。

业务配置修改频繁

在我们的业务中,往往又有许多的业务配置嵌入其中,比如功能开关、白名单、黑名单等。而这些配置,如果你的项目有接入一些业务配置系统还好,如果没有,那么又是需要发一波代码。

业务咨询

代码对于我们的业务方来说是不可见的,遇到一些根本不是问题的问题时,总是会向技术人员咨询。而你如果了解项目还好,但是一旦忘记,又需要去梳理一次业务逻辑。

幸福的家庭总是相似的,不幸的家庭却各有各的不同。处理这些看似不经意的小问题,总是会不经意间打断我们的思考。天下苦秦久已。
梳理一下,我们需要解决的事情至少有3点:

  1. 业务规则配置化。规则代码的编写,支持拔插和热更新。
  2. 业务配置可视化。业务配置应交由业务方自行处理。
  3. 业务咨询可见性。当业务遇到不清楚的问题时,可以非常清晰的在某个地方了解到原因所在。

经过调研,我们发现MVEL手册表达式非常适合我们去做这件事情。而支持MVEL表达式的开源规则引擎系统中,我们认为easy-rules更贴合我们的场景,一方面他支持MVEL,另一方面,他也支持在Java中自定义Rule,另外,他还支持自定义规则引擎。

但是,仅靠easy-rules并不能直接在使用生产环境中,我们需要针对自己的业务做一些调整,比如需要统一规则、需要统一属性注入、需要统一返回结构等等。

2020-05-08T15:16:58.png

我们大致画了一下我们业务执行的主要流程。首先需要注意的是,在业务中,肯定会有不同场景的情况,因此我们需要做好场景区隔,我们不可能将所有的东西都在一个地方去执行。因此我设计的适合有些地方参考了Java I/O这块的设计思路,有一个EngineProviders负责调度分发到不同的场景中。
每个场景都实现了统一的接口,而这个调度过程也是动态化的,尽可能较少我们开发同学所需要做的操作。

而在此之前,需要有一个统一的EngineService来统一的去获取我们配置的规则,去注入到场景中。同时,也需要把我们自定义的业务配置来注入到我们的数据源中。如下图所示:

2020-05-08T15:20:47.png

这里就是我们自定义的一些规则了,因为业务关系,打上了部分马赛克,不过应该并不妨碍理解这里所要做的事情。
2020-05-08T15:21:45.png

然而,我们在实际的业务中,还有很多地方都需要抽象的统一规则,因此,我们也可以借助easy-rules提供的能力来帮助我们完成这种事情。

2020-05-08T15:27:12.png

当然需要说明的是,还有一些细节没有补充上去,比如构参builder等,因为是根据我们业务自定义的,所以即使补充上去参考价值也不大。

最后还有一点,原因可视化的问题需要解决。其实这个相对而言就非常简单了,我们仅需要在阻断的地方记录当时的参数,以及阻断的规则,然后将其可视化,业务方自行查阅即可。

欢迎关注我的公众号,每周至少一篇比较有深度的原创文章:
2020-05-08T15:43:24.png