风控系统设计

一、思路

要实现一个简单的业务风控组件,要做什么工作呢?

1.风控规则的实现

a.需要实现的规则:

  • 自然日计数

  • 自然小时计数

  • 自然日+自然小时计数

自然日+自然小时计数 这里并不能单纯地串联两个判断,因为如果自然日的判定通过,而自然小时的判定不通过的时候,需要回退,自然日跟自然小时都不能计入本次调用!

b.计数方式的选择:

目前能想到的会有:

  • mysql+db事务 持久化、记录可溯源、实现起来比较麻烦,稍微“重”了一点

  • redis+lua 实现简单,redis的可执行lua脚本的特性也能满足对“事务”的要求

  • mysql/redis+分布式事务 需要上锁,实现复杂,能做到比较精确的计数,也就是真正等到代码块执行成功之后,再去操作计数

目前没有很精确技术的要求,代价太大,也没有持久化的需求,因此选用 redis+lua 即可

2.调用方式的实现

a.常见的做法 先定义一个通用的入口

//简化版代码@Component
class DetectManager {fun matchExceptionally(eventId: String, content: String){//调用规则匹配val rt = ruleService.match(eventId,content)if (!rt) {throw BaseException(ErrorCode.OPERATION_TOO_FREQUENT)}}
}

在service中调用该方法

//简化版代码@Service
class OcrServiceImpl : OcrService {@Autowiredprivate lateinit var detectManager: DetectManager/*** 提交ocr任务* 需要根据用户id来做次数限制*/override fun submitOcrTask(userId: String, imageUrl: String): String {detectManager.matchExceptionally("ocr", userId)//do ocr}}

有没有更优雅一点的方法呢? 用注解可能会更好一点(也比较有争议其实,这边先支持实现)

由于传入的 content 是跟业务关联的,所以需要通过Spel来将参数构成对应的content

二、具体实现

1.风控计数规则实现

a.自然日/自然小时

自然日/自然小时可以共用一套lua脚本,因为它们只有key不同,脚本如下:

//lua脚本
local currentValue = redis.call('get', KEYS[1]);
if currentValue ~= false then if tonumber(currentValue) < tonumber(ARGV[1]) then return redis.call('INCR', KEYS[1]);elsereturn tonumber(currentValue) + 1;end;
elseredis.call('set', KEYS[1], 1, 'px', ARGV[2]);return 1;
end;

其中 KEYS[1] 是日/小时关联的key,ARGV[1]是上限值,ARGV[2]是过期时间,返回值则是当前计数值+1后的结果,(如果已经达到上限,则实际上不会计数)

b.自然日+自然小时 如前文提到的,两个的结合实际上并不是单纯的拼凑,需要处理回退逻辑

//lua脚本
local dayValue = 0;
local hourValue = 0;
local dayPass = true;
local hourPass = true;
local dayCurrentValue = redis.call('get', KEYS[1]);
if dayCurrentValue ~= false then if tonumber(dayCurrentValue) < tonumber(ARGV[1]) then dayValue = redis.call('INCR', KEYS[1]);elsedayPass = false;dayValue = tonumber(dayCurrentValue) + 1;end;
elseredis.call('set', KEYS[1], 1, 'px', ARGV[3]);dayValue = 1;
end;local hourCurrentValue = redis.call('get', KEYS[2]);
if hourCurrentValue ~= false then if tonumber(hourCurrentValue) < tonumber(ARGV[2]) then hourValue = redis.call('INCR', KEYS[2]);elsehourPass = false;hourValue = tonumber(hourCurrentValue) + 1;end;
elseredis.call('set', KEYS[2], 1, 'px', ARGV[4]);hourValue = 1;
end;if (not dayPass) and hourPass thenhourValue = redis.call('DECR', KEYS[2]);
end;if dayPass and (not hourPass) thendayValue = redis.call('DECR', KEYS[1]);
end;local pair = {};
pair[1] = dayValue;
pair[2] = hourValue;
return pair;

其中 KEYS[1] 是天关联生成的key, KEYS[2] 是小时关联生成的key,ARGV[1]是天的上限值,ARGV[2]是小时的上限值,ARGV[3]是天的过期时间,ARGV[4]是小时的过期时间,返回值同上

这里给的是比较粗糙的写法,主要需要表达的就是,进行两个条件判断时,有其中一个不满足,另一个都需要进行回退.

2.注解的实现

a.定义一个@Detect注解

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
annotation class Detect(/*** 事件id*/val eventId: String = "",/*** content的表达式*/val contentSpel: String = "")

其中content是需要经过表达式解析出来的,所以接受的是个String

b.定义@Detect注解的处理类

@Aspect
@Component
class DetectHandler {private val logger = LoggerFactory.getLogger(javaClass)@Autowiredprivate lateinit var detectManager: DetectManager@Resource(name = "detectSpelExpressionParser")private lateinit var spelExpressionParser: SpelExpressionParser@Bean(name = ["detectSpelExpressionParser"])fun detectSpelExpressionParser(): SpelExpressionParser {return SpelExpressionParser()}@Around(value = "@annotation(detect)")fun operatorAnnotation(joinPoint: ProceedingJoinPoint, detect: Detect): Any? {if (detect.eventId.isBlank() || detect.contentSpel.isBlank()){throw illegalArgumentExp("@Detect config is not available!")}//转换表达式val expression = spelExpressionParser.parseExpression(detect.contentSpel)val argMap = joinPoint.args.mapIndexed { index, any ->"arg${index+1}" to any}.toMap()//构建上下文val context = StandardEvaluationContext().apply {if (argMap.isNotEmpty()) this.setVariables(argMap)}//拿到结果val content = expression.getValue(context)detectManager.matchExceptionally(detect.eventId, content)return joinPoint.proceed()}
}

需要将参数放入到上下文中,并起名为arg1arg2....

三、测试一下

1.写法

使用注解之后的写法:

//简化版代码@Service
class OcrServiceImpl : OcrService {@Autowiredprivate lateinit var detectManager: DetectManager/*** 提交ocr任务* 需要根据用户id来做次数限制*/@Detect(eventId = "ocr", contentSpel = "#arg1")override fun submitOcrTask(userId: String, imageUrl: String): String {//do ocr}}

2.Debug看看

  • 注解值获取成功

  • 表达式解析成功

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试-互联网金融风控测试知识都有哪些呢?

大家好&#xff0c;今天我们一起来聊聊&#xff0c;在我们测试互联网金融项目中的风控系统都需要怎么进行测试&#xff0c;测试工作中都有哪些内容需要进行测试&#xff0c;重点测试需要关注什么呢&#xff1f; 风控主要的测试节点&#xff1a; 1、用户预筛模型需要针对设计用…

将PPT中的文本提取到word文档

1、打开想要提取的PPT文件 2、按住 Altf11进入Microsoft Visual Basic for Applications 3、在左边的工程窗口空白处右键&#xff0c;选择 “插入”---“模块” 然后中间会出现一个代码编辑区 4、在最上方菜单栏找到“工具”点击选择“引用”&#xff0c;然后会弹出下面这个框…

TestGPT对研发和测试人员的变革

一、背景 上次我们我们聊到ChatGPT给测试工程师带来的机会和威胁 这次我们聊聊TestGPT对测试人员的影响。 TestGPT 模型旨在协助开发人员测试他们的代码&#xff0c;为开发人员提供自动生成的软件测试套件建议&#xff0c;从而加快编码和错误扫描。 一句话总结&#xff1a;…

2022年执法资格交通执法考试单选题专项训练题及答案

题库来源&#xff1a;优题宝公众号 2022年执法资格交通执法考试单选题专项训练题及答案&#xff0c;由优题宝公众号根据最新执法资格交通执法考试大纲与历年执法资格交通执法考试真题汇总编写&#xff0c;包含执法资格交通执法考试常考重点题型与知识点&#xff0c;有助于考生…

考试系统软件是怎么保障考试公平公正的?

通过考试系统软件组织在线考试,从出题、组卷、考试、阅卷、判分等一系统操作都可以在线上轻松实现。考试可以自主安排时间,不需要集中去考场,给考试组织方和考生都省去了不少麻烦。 就算考试系统软件智能好用,但还是有很多人担心作弊问题,在线上没有老师监考,考生在手机上…

2022年茶艺师(中级)培训试题及在线模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2022茶艺师&#xff08;中级&#xff09;操作考试题是茶艺师&#xff08;中级&#xff09;练习题考前押题&#xff01;2022年茶艺师&#xff08;中级&#xff09;培训试题及在线模拟考试根据茶艺师&#xff08;中级&a…

2022年最新浙江机动车签字授权人考试模拟题库及答案

百分百题库提供机动车签字授权人考试试题、机动车签字授权人考试真题、机动车签字授权人证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 判断题 102、汽车帮助驾驶员在所有的交通状况下尽可能安全避免事故的一种性能,称为被…

2022年自考专业考试(英语)外贸函电练习题

1、Because the voyage is in warm weather and the goods are liable to go mouldy, we think it advisable to have the shipment( ) the risk of mould. A.covered insurance B.taken out insured C.covered against D.insured for 2、 Our customers said that your…

2022年执法资格交通执法考试多选题专项训练题及答案

题库来源&#xff1a;优题宝公众号&#xff0c;2022年执法资格交通执法考试多选题专项训练题及答案&#xff0c;根据最新执法资格交通执法考试大纲与历年执法资格交通执法考试真题汇总编写&#xff0c;包含执法资格交通执法考试常考重点题型与知识点&#xff0c;有助于考生复习…

2020年茶艺师(高级)复审模拟考试及茶艺师(高级)模拟考试软件

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2020年茶艺师&#xff08;高级&#xff09;复审模拟考试及茶艺师&#xff08;高级&#xff09;模拟考试软件&#xff0c;包含茶艺师&#xff08;高级&#xff09;复审模拟考试答案和解析及茶艺师&#xff08;高级&…

2022年执法资格刑侦执法考试多选题专项训练题及答案

题库来源&#xff1a;优题宝公众号 2022年执法资格刑侦执法考试多选题专项训练题及答案&#xff0c;由优题宝公众号根据最新执法资格刑侦执法考试大纲与历年执法资格刑侦执法考试真题汇总编写&#xff0c;包含执法资格刑侦执法考试常考重点题型与知识点&#xff0c;有助于考生…

2022年最新江西机动车签字授权人考试模拟题及答案

百分百题库提供机动车签字授权人考试试题、机动车签字授权人考试真题、机动车签字授权人证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 249、对称设置、功能相同灯具的()不应有明显差异。 A、光色 B、光源类型 C、亮度 …

2021年劳务员-通用基础(劳务员)模拟考试题及劳务员-通用基础(劳务员)模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2021年劳务员-通用基础(劳务员)模拟考试题及劳务员-通用基础(劳务员)模拟考试题库&#xff0c;包含劳务员-通用基础(劳务员)模拟考试题答案和解析及劳务员-通用基础(劳务员)模拟考试题库练习。由安全生产模拟考试一点…

2022年企业法律顾问法律顾问实务考试模拟试题卷及答案

题库来源&#xff1a;优题宝公众号 2022年企业法律顾问法律顾问实务考试模拟试题卷及答案&#xff0c;由优题宝公众号根据最新企业法律顾问法律顾问实务考试大纲与历年企业法律顾问法律顾问实务考试真题汇总编写&#xff0c;包含企业法律顾问法律顾问实务考试常考重点题型与知…

2022年茶艺师(中级)上岗证题目及在线模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2022年茶艺师&#xff08;中级&#xff09;上岗证题库系茶艺师&#xff08;中级&#xff09;操作考试题精选题库&#xff01;2022年茶艺师&#xff08;中级&#xff09;上岗证题目及在线模拟考试根据茶艺师&#xff0…

PostgreSQL认证考试科目,PG考试说明及报名

PostgreSQL考试认证中心 (简称:PGCCC) 关于PostgreSQL数据库认证 经中国PostgreSQL考试认证中心&#xff08;简称&#xff1a;PGCCC&#xff09;研究决定&#xff0c;现下发2023年度中国PostgreSQL考试认证全年计划&#xff0c;具体内容如下&#xff1a; 2023年中国PostgreSQ…

2022年导游资格政策与法律法规考试模拟试题卷及答案

题库来源&#xff1a;优题宝公众号 2022年导游资格政策与法律法规考试模拟试题卷及答案&#xff0c;由优题宝公众号根据最新导游资格政策与法律法规考试大纲与历年导游资格政策与法律法规考试真题汇总编写&#xff0c;包含导游资格政策与法律法规考试常考重点题型与知识点&…

随着BCPNP邀请分数不断居于高位,申请人境外直接申请难度加大,大部分申请人需要先入境工作再递交省提名申请

当地时间4月19日&#xff0c;BC省省提名进行了新一轮的抽分&#xff0c;具体的最低抽选分数以及抽取人数如下&#xff1a; 目前对于直接用境外工作经验来申请BCPNP的A类岗位移民候选人来说&#xff0c;如果没有特别高的语言成绩&#xff0c;就需要先用LMIA工签入境工作满1年&am…

PPT文件设置打开密码的两种方法

PPT文件设置了打开密码加密&#xff0c;可以保护重要文件内容&#xff0c;今天介绍两种加密PPT文件的方法&#xff1a;第一种&#xff1a; 点击工具栏中的【文件】 然后点击【信息】-【保护演示文稿】-【用密码进行加密】 然后输入密码&#xff0c;就完成了对PPT文件的打开加…

人工智能先驱 Geoffrey Hinton 并不相信优秀的人工智能会战胜糟糕的人工智能

多伦多大学教授杰弗里辛顿&#xff08;Geoffrey Hinton&#xff09;因其对神经网络的开创性研究而经常被称为“人工智能教父”&#xff0c;最近成为该行业的非官方监管机构。今年春天&#xff0c;他辞去了谷歌的工作&#xff0c;更自由地批评他帮助开创的领域。他认为最近像Cha…