当前位置: 首页 > Web前端 > HTML

为什么要控制风险?

时间:2023-03-28 16:29:27 HTML

这不是产品大佬们的功劳。目前我们的业务用到了大量的AI能力,比如OCR识别、语音评价等,这些能力往往是昂贵的或者是资源密集型的,所以我们也希望能够在产品层面提升用户的能力。使用次数有一定的限制,风控是必须的!2、为什么要自己写风控?开源的风控组件那么多,为什么还要自己写?你想重新发明轮子吗?如果要回答这个问题,需要说明一下我们业务需要用到的风控(简称业务风控)和开源常见的风控(简称普通风控)的区别:riskcontroltypepurposeobjectrule业务风控实现了一些产品定义的Limit,当达到limit时,还有具体的业务流程,比如充值vip等,比较复杂多变,比如对用户的风控,以及用户+等级的风控。自然日、自然时间等常用风控保护服务或数据、异常请求拦截等接口和部分可以添加简单的参数。一般来说,滑动窗口的使用频率更高。所以直接使用开源的通用风控已经不能满足一般情况下的需求。3.其他要求支持实时调整,限制较多第一次设置限制值时,基本上是一个固定值。后续调整的可能性比较大,所以需要可调整,实时生效。2.思路是实现一个简单的业务风控组件,要做什么?1、风险控制规则的实现需要执行的规则:自然日计自然时计自然日+自然时计自然日+自然时计这里不能简单的把两个判断连起来,因为如果自然日的判断通过了,但是自然时的判断没有通过,需要回退,自然日和自然时都不能包含在这个调用中!b.统计方式的选择:目前能想到的会是:mysql+db事务持久化,记录溯源,实现起来比较麻烦,有点“重”的redis+lua实现起来容易,特点redis可执行lua脚本也可以满足“事务”的要求mysql/redis+分布式事务需要加锁,实现复杂,可以实现更准确的计数,即等待代码块执行成功,再操作计数。目前没有很精准的技术要求,成本太高,也没有持久化的必要,所以选择redis+lua就可以了2.调用方式a的实现。通常的做法是先定义一个公共入口//简化代码@ComponentclassDetectManager{funmatchExceptionally(eventId:String,content:String){//调用规则匹配valrt=ruleService.match(eventId,content)if(!rt){throwBaseException(ErrorCode.OPERATION_TOO_FREQUENT)}}}复制代码,在service中调用这个方法//简化代码@ServiceclassOcrServiceImpl:OcrService{@AutowiredprivatelateinitvardetectManager:DetectManager/***提交ocr任务*需要根据用户id限制次数*/overridefunsubmitOcrTask(userId:String,imageUrl:String):String{detectManager.matchExceptionally("ocr",userId)//做ocr}}有没有更优雅的复制代码的方法有哪些?使用注解可能会更好(也有争议,其实这里先支持实现)。由于传入的内容与业务相关,所以需要用Spel将参数组成相应的内容。三、具体实施1、风控计数规则的实现a.Naturalday/naturalhourNaturalday/naturalhour可以共用一套lua脚本,因为它们只是key不同,脚本如下://luascriptlocalcurrentValue=redis.call('get',KEYS[1]);ifcurrentValue~=falsetheniftonumber(currentValue)"arg${index+1}"toany}.toMap()//构建上下文valcontext=StandardEvaluationContext().apply{if(argMap.isNotEmpty())this.setVariables(argMap)}//获取结果valcontent=expression.getValue(context)detectManager.matchExceptionally(detect.eventId,content)returnjoinPoint.proceed()}}复制代码,需要把parametersintocontext,命名为arg1,arg2....4.测试一下1.使用注解写方法://简化版代码@ServiceclassOcrServiceImpl:OcrService{@AutowiredprivatelateinitvardetectManager:DetectManager/***提交ocrtask*需要根据用户id限制次数*/@Detect(eventId="ocr",contentSpel="#arg1")overridefunsubmitOcrTask(userId:String,imageUrl:String):String{//doocr}}复制代码2.调试看是否成功获取注解值,表达式解析成功