当前位置: 首页 > news >正文

风控规则引擎(一):Java 动态脚本

风控规则引擎(一):Java 动态脚本

日常场景

  1. 共享单车会根据微信分或者芝麻分来判断是否交押金
  2. 汽车租赁公司也会根据微信分或者芝麻分来判断是否交押金
  3. 在一些外卖 APP 都会提供根据你的信用等级来发放贷款产品
  4. 金融 APP 中会根据很复杂规则来判断用户是否有借款资格,以及贷款金额。

在简单的场景中,我们可以通过直接编写一些代码来解决需求,比如:

// 判断是否需要支付押金
return 芝麻分 > 650

这种方式代码简单,如果规则简单且不经常变化可以通过这种方式,在业务改变的时候,重新编写代码即可。

在金融场景中,往往会根据不同的产品,不同的时间,对接的银行等等多个维度来配置规则,单纯的直接编写代码无法满足业务需求,而且编写代码的方式对于运营人员来说无论实时性、可视化都很欠缺。

在这种情况往往会引入可视化的规则引擎,允许运营人员可以通过可视化配置的方式来实现一套规则配置,具有实时生效、可视化的效果。减少开发和运营的双重负担。

这篇主要介绍一下如何实现一个可视化的表达式的定义和执行。

表达式的定义

在上面说到的使用场景中,可以了解中至少需要支持布尔表达式。比如

  1. 芝麻分 > 650
  2. 居住地 不在 国外
  3. 年龄在 18 到 60 之间
  4. 名下无其他逾期借款

在上面的例子中,可以将一个表达式分为 3 个部分

  1. 规则参数 (ruleParam)
  2. 对应的操作 (operator)
  3. 对应操作的阈值 (args)

则可以将上面的布尔表达式表示为

  1. 芝麻分 > 650
{"ruleParam": "芝麻分","operator": "大于","args": ["650"]
}
  1. 居住地 不在 国外
{"ruleParam": "居住地","operator": "位于","args": ["国内"]
}
  1. 年龄在 18 到 60 之间
{"ruleParam": "年龄","operator": "区间","args": ["18""60"]
}
  1. 名下无其他逾期借款
{"ruleParam": "在途逾期数量","operator": "等于","args": ["0"]
}

表达式执行

上面的通过将表达式使用 json 格式定义出来,下面就是如何在运行中动态的解析这个 json 格式并执行。

有了 json 格式,可以通过以下方式来执行对应的表达式

  1. 因为表达式的结构已经定义好了,可以通过手写代码来判断所有的情况实现解释执行, 这种方案简单,但增加操作需要修改对应的解释的逻辑, 且性能低
/*
{"ruleParam": "在途逾期数量","operator": "等于","args": ["0"]
}
*/
switch(operator) {case "等于":// 等于操作break;case "大于":// 等于操作break;...
}
  1. 在第一次得到 json 字符串的时候,直接将其根据不同的情况生成对应的 java 代码,并动态编译成 Java Class,方便下一次执行,该方案依然需要处理各种情况,但因为在第一次编译成了 java 代码,性能和直接编写 java 代码一样

  2. 使用第三方库实现表达式的执行

使用第三方库实现动态表达式的执行

在 Java 中有很多表达式引擎,常见的有

  1. jexl3
  2. mvel
  3. spring-expression
  4. QLExpress
  5. groovy
  6. aviator
  7. ognl
  8. fel
  9. jsel

这里简单介绍一下 jexl3 和 aviator 的使用

jexl3 在 apache commons-jexl3 中,该表达式引擎比较符合人的书写习惯,其会判断操作的类型,并将参数转换成对应的类型比如 3 > 4 和 “3” > 4 这两个的执行结果是一样的

aviator 是一个高性能的 Java 的表达式类型,其要求确定参数的类型,比如上面的 “3” > 4 在 aviator 是无法执行的。

jexl3 更适合让运营手动编写的情况,能容忍一些错误情况;aviator 适合开发来使用,使用确定的类型参数来提供性能

jexl3 使用

加入依赖

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-jexl3</artifactId><version>3.2.1</version>
</dependency>
// 创建一个带有缓存 jexl 表达式引擎,
JexlEngine JEXL = new JexlBuilder().cache(1000).strict(true).create();// 根据表达式字符串来创建一个关于年龄的规则
JexlExpression ageExpression = JEXL.createExpression("age > 18 && age < 60");// 获取需要的参数,java 代码太长了,简写一下
Map<String, Object> parameters parameters = {"age": 30}// 执行一下
JexlContext jexlContext = new MapContext(parameters);boolean result = (boolean) executeExpression.evaluate(jexlContext);

以上就会 jexl3 的简单使用

aviator

引入依赖

<dependency><groupId>com.googlecode.aviator</groupId><artifactId>aviator</artifactId><version>5.3.1</version>
</dependency>
Expression ageExpression = executeExpression = AviatorEvaluator.compile("age > 18 && age < 60");// 获取需要的参数,java 代码太长了,简写一下
Map<String, Object> parameters parameters = {"age": 30}boolean result = (boolean) ageExpression.execute(parameters);

注意 aviator 是强类型的,需要注意传入 age 的类型,如果 age 是字符串类型需要进行类型转换

性能测试

不同表达式引擎的性能测试

Benchmark                                         Mode  Cnt           Score           Error  Units
Empty              thrpt    3  1265642062.921 ± 142133136.281  ops/s
Java               thrpt    3    22225354.763 ±  12062844.831  ops/s
JavaClass          thrpt    3    21878714.150 ±   2544279.558  ops/s
JavaDynamicClass   thrpt    3    18911730.698 ±  30559558.758  ops/s
GroovyClass        thrpt    3    10036761.622 ±    184778.709  ops/s
Aviator            thrpt    3     2871064.474 ±   1292098.445  ops/s
Mvel               thrpt    3     2400852.254 ±     12868.642  ops/s
JSEL               thrpt    3     1570590.250 ±     24787.535  ops/s
Jexl               thrpt    3     1121486.972 ±     76890.380  ops/s
OGNL               thrpt    3      776457.762 ±    110618.929  ops/s
QLExpress          thrpt    3      385962.847 ±      3031.776  ops/s
SpEL               thrpt    3      245545.439 ±     11896.161  ops/s
Fel                thrpt    3       21520.546 ±     16429.340  ops/s
GroovyScript       thrpt    3          91.827 ±       106.860  ops/s

总结

这是写的规则引擎的第一篇,主要讲一下

  1. 如何讲一个布尔表达式转换为 json 格式的定义方便做可视化存储和后端校验
  2. 如何去执行一个 json 格式的表达式定义

在这里也提供了一些不同的表达式引擎和性能测试,如果感兴趣的可以去尝试一下。

下一篇主要讲一下在引擎里面规则参数、操作符是如何设计的,也讲一下可视化圆形的设计

相关文章:

风控规则引擎(一):Java 动态脚本

风控规则引擎&#xff08;一&#xff09;&#xff1a;Java 动态脚本 日常场景 共享单车会根据微信分或者芝麻分来判断是否交押金汽车租赁公司也会根据微信分或者芝麻分来判断是否交押金在一些外卖 APP 都会提供根据你的信用等级来发放贷款产品金融 APP 中会根据很复杂规则来判…...

第五十六天|583. 两个字符串的删除操作 72. 编辑距离

583. 两个字符串的删除操作 可以求出最大子序列然后用字符串长度去减&#xff0c;也可以用删除的思路&#xff0c;如下&#xff1a; class Solution { public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word1.size()1,vector<int…...

java中Lists.newArrayList和new ArrayList的详细区别?

下面是对Lists.newArrayList()和new ArrayList<>()的详细区别进行举例说明&#xff1a; 创建具有初始数据的列表&#xff1a; java Copy code import com.google.common.collect.Lists; List<String> list1 Lists.newArrayList("apple", "banana…...

从图片或PDF文件识别表格提取内容的简单库img2table

img2table是一个基于OpenCV 图像处理的用于 PDF 和图像的表识别和提取 Python库。由于其设计基于神经网络的解决方案&#xff0c;提供了一种实用且更轻便的替代方案&#xff0c;尤其是在 CPU 上使用时。 该库的特点&#xff1a; 识别图像和PDF文件中的表格&#xff0c;包括在表…...

CSV文件中使用insert 函数在指定列循环插入不同数据

文章目录 一、系统、工具要求二、需求三、代码实现&#xff1a;四、核心代码解读五、逐行更改某一列数据六&#xff1a;实现在文件的末尾增加指定内容列 一、系统、工具要求 pandaspythoncsv Windows 系统 二、需求 我有两个文件&#xff1a; 文件一&#xff1a;subject_ma…...

【华为OD题库-064】最小传输时延I-java

题目 某通信网络中有N个网络结点&#xff0c;用1到N进行标识。网络通过一个有向无环图.表示,其中图的边的值表示结点之间的消息传递时延。 现给定相连节点之间的时延列表times[]{u&#xff0c;v&#xff0c; w)&#xff0c;其中u表示源结点&#xff0c;v表示目的结点&#xff0…...

全文检索[ES系列] - 第495篇

历史文章&#xff08;文章累计490&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 M…...

【预计IEEE出版|EI征稿通知】第六届下一代数据驱动网络国际学术会议 (NGDN 2024)

第六届下一代数据驱动网络国际学术会议 (NGDN 2024) The Sixth International Conference on Next Generation Data-driven Networks 2024年4月26-28日 | 中国沈阳 基于前几届在英国埃克塞特 (ISPA 2020) 、中国沈阳 (TrustCom 2021) 和中国武汉 (IEEETrustCom-2022) 成功举…...

C++软件在Win平台运行总结

Windows平台&#xff1a; 1.需要安装运行库&#xff1a;无论是exe还是动态库用的哪种平台工具集(visual2010-visual2019)进行编译&#xff0c;需要安装对应的运行时库vc_redist.x64.exe/vc_redist.x86.exe。比如Exe用的是VisualStdio2010工具集编译&#xff0c;其中链接的一个…...

【数电笔记】16-卡诺图绘制(逻辑函数的卡诺图化简)

目录 说明&#xff1a; 最小项卡诺图的组成 1. 相邻最小项 2. 卡诺图的组成 2.1 二变量卡诺图 2.2 三表变量卡诺图 2.3 四变量卡诺图 3. 卡诺图中的相邻项&#xff08;几何相邻&#xff09; 说明&#xff1a; 笔记配套视频来源&#xff1a;B站&#xff1b;本系列笔记并…...

前端面试灵魂提问(1)

1.自我介绍 2.在实习中&#xff0c;你负责那一模块 3.any与unknow的异同 相同点&#xff1a;any和unkonwn 可以接受任何值 不同点&#xff1a;any会丢掉类型限制&#xff0c;可以用any 类型的变量随意做任何事情。unknown 变量会强制执行类型检查&#xff0c;所以在使用一个…...

Linux中项目部署步骤

安装jdk&#xff0c;tomcat 安装步骤 1&#xff0c;将压缩包&#xff0c;拷贝到虚拟机中。 通过工具&#xff0c;将文件直接拖到虚拟机的/home下 2&#xff0c;回到虚拟机中&#xff0c;查看/home下&#xff0c;有两个压缩文件 3&#xff0c;给压缩文件做解压缩操作 tar -z…...

cmd下查看python命令的用法

在cmd下&#xff0c;可以运行python --help或者py --help来查看python命令的用法。例如&#xff1a;...

大型语言模型在实体关系提取中的应用探索(二)

上一篇文章我们探讨了如何使用大语言模型进行实体关系的抽取。本篇文章我们将进一步探索这个话题。比较一下国内外几款知名大模型在相同的实体关系提取任务下的表现。由于精力有限&#xff0c;我们无法全面测试各模型的实体关系抽取能力&#xff0c;因此&#xff0c;看到的效果…...

Easy Excel设置表格样式

1. 设置通用样式 import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.xxx.npi.config.easypoi.EasyExcelDateConverter; import lombok.Data; import …...

HarmonyOS/OpenHarmony应用开发

OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目, 目标是面向全场景、全连接、全智能时代, 搭建一个智能终端设备操作系统的框架和平台, 促进万物互联产业的繁荣发展。 了解OpenHarmony HarmonyOS是华为通过OpenHarmony项目&#xff0c;结合商业…...

孩子都能学会的FPGA:第二十一课——用线性反馈移位寄存器实现伪随机序列

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…...

国内 AI 成图第一案!你来你会怎么判?

我国目前并未出台专门针对网络爬虫技术的法律规范&#xff0c;但在司法实践中&#xff0c;相关判决已屡见不鲜&#xff0c;K 哥特设了“K哥爬虫普法”专栏&#xff0c;本栏目通过对真实案例的分析&#xff0c;旨在提高广大爬虫工程师的法律意识&#xff0c;知晓如何合法合规利用…...

快速登录界面关于如何登录以及多账号列表解析以及config配置文件是如何读取(1)

快速登录界面关于如何登录以及多账号列表解析以及config配置文件是如何读取 1、快速登录界面关于如何登录以及快速登录界面账号如何显示 如图所示:根据按下按钮一键登录中途会发生什么。 关于一键登录按钮皮肤skin的设置: <Button name"QuickLoginOkBtn" text&q…...

finebi 新手入门案例

finebi 新手入门案例 连锁超市销售数据分析 步骤&#xff1a; 准备公共数据新建分析主题处理数据在数据中分析在图形中分析数据大屏 准备公共数据 点击公共数据 点击新建文件夹 修改文件夹名称 上传数据 鼠标悬停在文件夹上&#xff0c;右侧出现 鼠标悬停在文件夹上&#x…...

LeagueAkari终极指南:智能游戏辅助工具快速上手与深度配置

LeagueAkari终极指南&#xff1a;智能游戏辅助工具快速上手与深度配置 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否曾在…...

开源项目主题系统的3大核心机制深度解析:从CSS变量到动态切换的完整实现方案

开源项目主题系统的3大核心机制深度解析&#xff1a;从CSS变量到动态切换的完整实现方案 【免费下载链接】vue-vben-admin vbenjs/vue-vben-admin: 是一个基于 Vue.js 和 Element UI 的后台管理系统&#xff0c;支持多种数据源和插件扩展。该项目提供了一个完整的后台管理系统&…...

【adb端口5555】烽火hg680系列安卓9线刷全攻略:告别强制升级与花屏困扰

1. 烽火HG680系列机顶盒的痛点与解决方案 最近在折腾烽火HG680-GY和HG680-GC这两款机顶盒的朋友应该都深有体会&#xff0c;官方系统用着用着就会弹出强制升级提示&#xff0c;有时候还会莫名其妙出现花屏问题。作为一个折腾过不下20台烽火盒子的老玩家&#xff0c;我太理解这种…...

手把手教你解决Unity视频播放问题:H264编码设置与RawImage的正确用法

Unity视频播放全攻略&#xff1a;H264编码优化与RawImage实战解析 在Unity项目开发中&#xff0c;视频播放功能看似简单&#xff0c;却暗藏诸多技术细节。许多开发者都曾遇到过视频不同步、颜色失真或性能低下的困扰。本文将深入剖析视频播放的核心技术要点&#xff0c;从编码格…...

实战演练:在快马平台模拟静电地板排布与支架系统配置方案

今天想和大家分享一个特别实用的工具——在InsCode(快马)平台上快速搭建的静电地板施工模拟器。作为机房建设中的重要环节&#xff0c;静电地板施工的合理规划直接影响后期使用效果。这个工具能帮我们在实际施工前&#xff0c;通过可视化模拟规避很多潜在问题。 核心功能设计思…...

League-Toolkit完全指南:高效BP策略与全方位战绩分析实战应用

League-Toolkit完全指南&#xff1a;高效BP策略与全方位战绩分析实战应用 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 功能解析…...

OZON跨境电商的供应链之痛:爆单AI选品后为什么你拿货比别人贵?

选品决定利润的上限&#xff0c;供应链决定利润的下限做跨境电商&#xff0c;有一个残酷的事实&#xff1a;同样的商品&#xff0c;你卖100块&#xff0c;利润20块。别人卖90块&#xff0c;利润还有25块。为什么&#xff1f;不是你卖得不好&#xff0c;不是你运营不行&#xff…...

java 短信验证码接口开发面向接口编程实现

在Java企业级后端开发中&#xff0c;短信验证码是用户登录、注册、密码重置的核心身份验证方案&#xff0c;java短信验证码接口的规范化开发直接决定系统的扩展性与维护性。传统硬编码开发模式存在耦合度高、服务商切换困难等问题&#xff0c;本文基于面向接口编程思想&#xf…...

别再只用交叉熵了!医疗AI中疾病分级任务,试试PyTorch实现这个序数回归损失函数

医疗AI中的序数回归&#xff1a;超越交叉熵的疾病分级新范式 在医疗人工智能领域&#xff0c;我们经常遇到需要预测疾病严重程度分级的任务——从轻度到中度再到重度&#xff0c;这些类别之间存在明确的递进关系。传统做法是直接套用交叉熵损失函数&#xff0c;但这就像用尺子测…...

华为eNSP实战:三层交换机VLAN间通信配置避坑指南(附CE12800特殊命令)

华为eNSP三层交换机VLAN间通信实战&#xff1a;从基础配置到核心设备差异解析 在华为eNSP模拟器的学习过程中&#xff0c;三层交换机配置是网络工程师必须掌握的硬核技能。不同于传统二层交换&#xff0c;三层交换技术融合了路由与交换的优势&#xff0c;能够高效实现VLAN间通信…...