Down首页投稿(暂停使用,暂停投稿)程序员

实时业务风控系统

2016-08-07  本文已影响3622人  sunpeak

项目地址

代码已开源, https://github.com/sunpeak/riskcontrol

背景

当前互联网企业存在很多业务风险,有些风险(比如薅羊毛)虽然没有sql注入漏洞利用来的直接,但是一直被羊毛党、刷单党光顾的企业长期生存下来的几率会很低!

项目介绍

实时业务风控系统是分析风险事件,根据场景动态调整规则,实现自动精准预警风险的系统。

本项目只提供实时风控系统框架基础和代码模板。

需要解决的问题

项目标签

原理

统计学

通用公式:某时间段,在条件维度(可以是多个维度复合)下,利用统计方法统计结果维度的值,充分发挥你的想象吧!

实时计算

要将任意维度的历史数据(可能半年或更久)实时统计出结果,需要将数据提前安装特殊结果准备好(由于事件的维度数量不固定的,选取统计的维度也是随意的,所以不是在关系数据库中建几个索引就能搞定的),需要利用空间换时间,来降低时间复杂度。

redis

redis中数据结构sortedset,是个有序的集合,集合中只会出现最新的唯一的值。利用sortedset的天然优势,做频数统计非常有利。

比如1小时内某ip上出现的账号数量统计:

结构如下:

1.1.1.1

|--账号1        20160807121314

|--账号2        20160807121315

|--账号n        20160807121316


2.2.2.2

|--账号3        20160807121314

|--账号4        20160807121315

|--账号m        20160807121316

mongodb

mongodb本身的聚合函数统计维度,支持很多比如:max,min,sum,avg,first,last,标准差,采样标准差,复杂的统计方法可以在基础聚合函数上建立,比如行为习惯:

getDB().getCollection(collectionName).aggregate(

  Arrays.asList(

    match(match)                                                       --匹配条件维度

    , group("$" + field, Accumulators.sum("_count", 1))                --求值维度的次数

    , match(new Document("_count", new Document("$gte", minCount)))   --过滤,超过minCount才统计

    , sort(new Document("_count", -1))                                --对次数进行倒叙排列

  )

);

建议在mongodb聚合的维度上建立索引,这样可以使用内存计算,速度较快。

redis性能优于mongodb,所以使用场景较多的频数计算默认在redis中运行,参考代码DimensionService.distinctCountWithRedis方法。但是redis为了性能牺牲了很多空间,数据重复存储,会占用很多内存。

环境准备

项目配置

单个规则文件说明:

package rules;                                        --规则包路径

import com.example.riskcontrol.model.LoginEvent        --引入类

import com.example.riskcontrol.service.DimensionService

import com.example.riskcontrol.model.EnumTimePeriod

global DimensionService dimensionService             --引入外部服务

rule "98_login_ip"                                   --规则名称,全局唯一

  salience 98                                        --规则优先级,值越大越先执行

  lock-on-active true                                --事件不重复执行该规则

when                                                 --条件判断,是否需要进入action

  event:LoginEvent()                                --判断事件对象是否是LoginEvent类

then                                                --action

  int count  = dimensionService.distinctCount(event,new String[]{LoginEvent.OPERATEIP},EnumTimePeriod.LASTHOUR,LoginEvent.MOBILE);        --近1小时内该事件ip上出现的mobile数量统计

  if(event.addScore(count,20,10,1)){        --如果统计结果超过20个,则记10分,并且结果每超1个,再多记1分

    dimensionService.insertRiskEvent(event,"近1小时内同ip出现多个mobile,count="+count);  --记录风险事件日志

  }

end       --结束规则

drools的详细文档,请参考官方http://docs.jboss.org/drools/release/6.4.0.Final/drools-docs/html_single/index.html

部署

系统默认采用jar打包和运行,建议集群方式部署,然后使用反向代理做负载均衡。

打包

mvn clean install

运行

建议jdk 8

java -jar riskcontrol-*.jar

war包部署

如果需要tomcat等容器部署,也可将配置打包方式修改成war包方式,修改pom.xml

 <packaging>war</packaging>

风控分析入口

TODO

上一篇 下一篇

猜你喜欢

热点阅读