您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

网易考拉规则引擎平台架构设计与实践

时间:2021-04-01 11:34:11  来源:今日头条  作者:数字化生存King

背景

考拉安全部技术这块目前主要负责两块业务:一个是内审,主要是通过敏感日志管理平台搜集考拉所有后台系统的操作日志,数据导入到es后,结合storm进行实时计算,主要有行为查询、数据监控、事件追溯、风险大盘等功能;一个是业务风控,主要是下单、支付、优惠券、红包、签到等行为的风险控制,对抗的风险行为包括黄牛刷单、恶意占用库存、机器领券、撸羊毛等。这两块业务其实有一个共通点,就是有大量需要进行规则决策的场景,比如内审中需要进行实时监控,当同一个人在一天时间内的导出操作超过多少次后进行告警,当登录时不是常用地登录并且设备指纹不是该账号使用过的设备指纹时告警。而在业务风控中需要使用到规则决策的场景更多,由于涉及规则的保密性,这里就不展开了。总之,基于这个出发点,安全部决定开发出一个通用的规则引擎平台,来满足以上场景。

写在前面

在给出整体架构前,想跟大家聊聊关于架构的一些想法。目前架构上的分层设计思想已经深入人心,大家都知道要分成controller,server,dao等,是因为我们刚接触到编码的时候,mvc的模型已经大行其道,早期的jsp里面包含大量业务代码逻辑的方式已经基本绝迹。但是这并不是一种面向对象的思考方式,而往往我们是以一种面向过程的思维去编程。举个简单例子,我们要实现一个网银账户之间转账的需求,往往会是下面这种实现方式:

  1. 设计一个账户交易服务接口AccountingService,设计一个服务方法transfer(),并提供一个具体实现类AccountingServiceImpl,所有账户交易业务的业务逻辑都置于该服务类中。
  2. 提供一个AccountInfo和一个Account,前者是一个用于与展示层交换账户数据的账户数据传输对象,后者是一个账户实体(相当于一个EntityBean),这两个对象都是普通的JAVABean,具有相关属性和简单的get/set方法。
  3. 然后在transfer方法中,首先获取A账户的余额,判断是否大于转账的金额,如果大于则扣减A账户的余额,并增加对应的金额到B账户。

这种设计在需求简单的情况下看上去没啥问题,但是当需求变得复杂后,会导致代码变得越来越难以维护,整个架构也会变的腐烂。比如现在需要增加账户的信用等级,不同等级的账户每笔转账的最大金额不同,那么我们就需要在service里面加上这个逻辑。后来又需要记录转账明细,我们又需要在service里面增加相应的代码逻辑。最后service代码会由于需求的不断变化变得越来越长,最终变成别人眼中的“祖传代码”。导致这个问题的根源,我认为就是我们使用的是一种面向过程的编程思想。那么如何去解决这种问题呢?主要还是思维方式上需要改变,我们需要一种真正的面向对象的思维方式。比如一个“人”,除了有id、姓名、性别这些属性外,还应该有“走路”、“吃饭”等这些行为,这些行为是天然属于“人”这个实体的,而我们定义的bean都是一种“失血模型”,只有get/set等简单方法,所有的行为逻辑全部上升到了service层,这就导致了service层过于臃肿,并且很难复用已有的逻辑,最后形成了各个service之间错综复杂的关联关系,在做服务拆分的时候,很难划清业务边界,导致服务化进程陷入泥潭。

对应上面的问题,我们可以在Account这个实体中加入本应该就属于这个实体的行为,比如借记、贷记、转账等。每一笔转账都对应着一笔交易明细,我们根据交易明细可以计算出账户的余额,这个是一个潜在的业务规则,这种业务规则都需要交由实体本身来维护。另外新增账户信用实体,提供账户单笔转账的最大金额计算逻辑。这样我们就把原本全部在service里面的逻辑划入到不同的负责相关职责的“领域对象”当中了,service的逻辑变得非常清楚明了,想实现A给B转账,直接获取A实体,然后调用A实体中的转账方法即可。service将不再关注转账的细节,只负责将相关的实体组织起来,完成复杂的业务逻辑处理。

上面的这种架构设计方式,其实就是一种典型的“领域驱动设计(DDD)”思想,在这里就不展开说明了(主要是自己理解的还不够深入,怕误导大家了)。DDD也是目前非常热门的一种架构设计思想了,它不能减少你的代码量,但是能使你的代码具有很高的内聚性,当你的项目变得越来越复杂时,能保持架构的稳定而不至于过快的腐烂掉,不了解的同学可以查看相关资料。要说明的是,没有一种架构设计是万能的、是能解决所有问题的,我们需要做的是吸收好的架构设计思维方式,真正架构落地时还是需要根据实际情况选择合适的架构。

整体架构设计

上面说了些架构设计方面的想法,现在我们回到规则引擎平台本身。我们抽象出了四个分层,从上到下分别为:服务层、引擎层、计算层和存储层,整个逻辑层架构见下图:

网易考拉规则引擎平台架构设计与实践

 

  • 服务层:服务层主要是对外提供服务的入口层,提供的服务包括数据分析、风险检测、业务决策等,所有的服务全部都是通过数据接入模块接入数据,具体后面讲
  • 引擎层:引擎层是整个平台的核心,主要包括了执行规则的规则引擎、还原事件现场和聚合查询分析的查询引擎以及模型预测的模型引擎
  • 计算层:计算层主要包括了指标计算模块和模型训练模块。指标会在规则引擎中配置规则时使用到,而模型训练则是为模型预测做准备
  • 存储层:存储层包括了指标计算结果的存储、事件信息详情的存储以及模型样本、模型文件的存储

在各个分层的逻辑架构划定后,我们就可以开始分析整个平台的业务功能模块。主要包括了事件接入模块、指标计算模块、规则引擎模块、运营中心模块,整个业务架构如下图:

网易考拉规则引擎平台架构设计与实践

 

1.事件接入中心

事件接入中心主要包括事件接入模块和数据管理模块。数据接入模块是整个规则引擎的数据流入口,所有的业务方都是通过这个模块接入到平台中来。提供了实时(dubbo)、准实时(kafka)和离线(hive)三种数据接入方式。数据管理模块主要是进行事件的元数据管理、标准化接入数据、补全必要的字段,如下图:

网易考拉规则引擎平台架构设计与实践

 

2.指标计算模块

指标计算模块主要是进行指标计算。一个指标由主维度、从维度、时间窗口等组成,其中主维度至少有一个,从维度最多有一个。如下图:

网易考拉规则引擎平台架构设计与实践

 

举个例子,若有这样一个指标:“最近10分钟,同一个账号在同一个商家的下单金额”,那么主维度就是下单账号+商家id,从维度就是订单金额。可以看到,这里的主维度相当于sql里面的group by,从维度相当于count,数值累加相当于sum。从关于指标计算,有几点说明下:

  1. key的构成。我们的指标存储是用的redis,那么这里会涉及到一个key该如何构建的问题。我们目前的做法是:key=指标id+版本号+主维度值+时间间隔序号。
    • 指标id就是指标的唯一标示;
    • 版本号是指标对象的版本,每次更新完指标都会更新对应的版本号,这样可以让就的指标一次全部失效;
    • 主维度值是指当前事件对象中,主维度字段对应的值,比如一个下单事件,主维度是用户账号,那么这里就是对应的类似XXX@163.com,如果有多个主维度则需要全部组装上去;
    • 如果主维度的值出现中文,这样直接拼接在key里面会有问题,可以采用转义或者md5的方式进行。
    • 时间间隔序号是指当前时间减去指标最后更新时间,得到的差值再除以采样周期,得到一个序号。这么做主要是为了实现指标的滑动窗口计算,下面会讲
  1. 滑动窗口计算。比如我们的指标是最近10分钟的同一用户的下单量,那么我们就需要实现一种类似的滑动窗口算法,以便任何时候都能拿到“最近10分钟”的数据。这里我们采用的是一种简单的算法:创建指标时,指定好采样次数。比如要获取“最近10分钟”的数据,采样次数设置成30次,这样我们会把每隔20秒的数据会放入一个key里面。每次一个下单事件过来时,计算出时间间隔序号(见第1点),然后组装好key之后看该key是否存在,存在则进行累计,否则往redis中添加该key。
  2. 如何批量获取key。每次获取指标值时,我们都是先计算出需要的key集合(比如我要获取“单个账号最近10分钟的下单量”,我可能需要获取30个key,因为每个key的跨度是20s),然后获取到对应的value集合,再进行累加。而实际上我们只是需要累加后的值,这里可以通过redis+lua脚本进行优化,脚本里面直接根据key集合获取value后进行累加然后返回给客户端,这样就较少了每次响应的数据量。
  3. 如何保证指标的计算结果不丢失?目前的指标是存储在redis里面的,后来会切到solo-ldb,ldb提供了持久化的存储引擎,可以保证数据不丢失。

3.规则引擎模块

计划开始做规则引擎时进行过调研,发现很多类似的平台都会使用drools。而我们从一开始就放弃了drools而全部使用groovy脚本实现,主要是有以下几点考虑:

  • drools相对来说有点重,而且它的规则语言不管对于开发还是运营来说都有学习成本
  • drools使用起来没有groovy脚本灵活。groovy可以和spring完美结合,并且可以自定义各种组件实现插件化开发。
  • 当规则集变得复杂起来时,使用drools管理起来有点力不从心。

当然还有另外一种方式是将drools和groovy结合起来,综合双方的优点,也是一种不错的选择,大家可以尝试一下。

规则引擎模块是整个平台的核心,我们将整个模块分成了以下几个部分:

网易考拉规则引擎平台架构设计与实践

 

规则引擎在设计中也碰到了一些问题,这里给大家分享下一些心得:

  • 使用插件的方式加载各种组件到上下文中,极大的方便了功能开发的灵活性。
  • 使用预加载的方式加载已有的规则,并将加载后的对象缓存起来,每次规则变更时重新load整条规则,极大的提升了引擎的执行效率
  • 计数器引入AtomicLongFieldUpdater工具类,来减少计数器的内存消耗
  • 灵活的上下文使用方式,方便定制规则执行的流程(规则执行顺序、同步异步执行、跳过某些规则、规则集短路等),灵活定义返回结果(可以返回整个上下文,可以返回每条规则的结果,也可以返回最后一条规则的结果),这些都可以通过设置上下文来实现。
  • groovy的方法查找策略,默认是从metaClass里面查找,再从上下文里找,为了提升性能,我们重写了metaClass,修改了这个查询逻辑:先从上下文里找,再从metaClass里面找。

规则配置如下图所示:

网易考拉规则引擎平台架构设计与实践

 

未来规划

后面规则引擎平台主要会围绕下面几点来做:

  1. 指标存储计划从redis切换到hbase。目前的指标计算方式会导致缓存key的暴涨,获取一个指标值可能需要N个key来做累加,而换成hbase之后,一个指标就只需要一条记录来维护,使用hbase的列族来实现滑动窗口的计算。
  2. 规则的灰度上线。当一条新规则创建后,如果不进行灰度的测试,直接上线是可能会带来灾难的。后面再规则上线流程中新增灰度上线环节,整个引擎会根据配置的灰度比例,复制一定的流量到灰度规则中,并对灰度规则的效果进行展示,达到预期效果并稳定后才能审批上线。
  3. 事件接入的自动化。dubbo这块可以采用泛化调用,http接口需要统一调用标准,消息需要统一格式。有了统一的标准就可以实现事件自动接入而不需要修改代码上线,这样也可以保证整个引擎的稳定性。
  4. 模型生命周期管理。目前模型这块都是通过在猛犸平台上提交jar包的方式,离线跑一个model出来,没有一个统一的平台去管控整个模型的生命周期。现在杭研已经有类似的平台了,后续需要考虑如何介入。
  5. 数据展示优化。现在整个平台的数字化做的比较弱,没法形成数据驱动业务。而风控的运营往往是需要大量的数据去驱动规则的优化的,比如规则阈值的调试、规则命中率、风险大盘等都需要大量数据的支撑。


Tags:架构设计   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
背景在日常工作中,我们通常需要存储一些日志,譬如用户请求的出入参、系统运行时打印的一些info、error之类的日志,从而对系统在运行时出现的问题有排查的依据。日志存储和检索...【详细内容】
2021-11-23  Tags: 架构设计  点击:(20)  评论:(0)  加入收藏
如何设计一个好的软件架构,如何提高软件的扩展性,移植性,复用性和可读性?很多做嵌入式开发的朋友经常会遇到这种情况:一个项目软件设计完成了,客户提出了一些新的功能需求。这时侯...【详细内容】
2021-11-08  Tags: 架构设计  点击:(35)  评论:(0)  加入收藏
1、网络架构总体说明为了方便网络管理,园区网络通常按照功能或业务进行分层分区设计,园区内部网络包括终端层、接入层、汇聚层、核心层、出口区,园区外部的其他园区、分支、出...【详细内容】
2021-08-17  Tags: 架构设计  点击:(89)  评论:(0)  加入收藏
一:业务背景优惠券是电商常见的营销手段,具有灵活的特点,既可以作为促销活动的载体,也是重要的引流入口。优惠券系统是vivo商城营销模块中一个重要组成部分,早在15年vivo商城还是...【详细内容】
2021-08-06  Tags: 架构设计  点击:(74)  评论:(0)  加入收藏
组织结构是企业的骨架,是实现战略目标的载体,是企业运营的支撑,是岗位设置的依据,是企业信息流的渠道。如果企业缺乏合理的组织结构,就会造成分工不明确、权责不清楚、沟通渠道不...【详细内容】
2021-06-08  Tags: 架构设计  点击:(120)  评论:(0)  加入收藏
1. 前言嵌入式是软件设计领域的一个分支,它自身的诸多特点决定了系统架构师的选择,同时它的一些问题又具有相当的通用性,可以推广到其他的领域。提起嵌入式软件设计,传统的印象...【详细内容】
2021-04-15  Tags: 架构设计  点击:(250)  评论:(0)  加入收藏
背景考拉安全部技术这块目前主要负责两块业务:一个是内审,主要是通过敏感日志管理平台搜集考拉所有后台系统的操作日志,数据导入到es后,结合storm进行实时计算,主要有行为查询、...【详细内容】
2021-04-01  Tags: 架构设计  点击:(259)  评论:(0)  加入收藏
简介: 作为一名Java程序员,相信同学们都听说过微内核架构设计,也有自己的理解。那么微内核是如何被提出来的?微内核在操作系统内核的设计中又有什么作用?本文从插件化(Plug-in)架...【详细内容】
2021-02-24  Tags: 架构设计  点击:(158)  评论:(0)  加入收藏
由于多年前开发了一款聊天软件,今天朋友给我打电话,说他们公司准备开发一款内部使用的沟通交流工具,找我咨询关于即时聊天软件一些经验,于是跟他聊了一些关于这方面的东西,所以在...【详细内容】
2020-12-22  Tags: 架构设计  点击:(282)  评论:(0)  加入收藏
Nginx+Redis+MQ+DB下秒杀实现原理 Nginx+Redis+MQ+DB下限购实现原理 Nginx+Redis+MQ+DB下亿级流量实现原理 Redis在架构中的意义 分布式微服务是快了还是慢了 高可用和可用...【详细内容】
2020-12-22  Tags: 架构设计  点击:(364)  评论:(0)  加入收藏
▌简易百科推荐
为了构建高并发、高可用的系统架构,压测、容量预估必不可少,在发现系统瓶颈后,需要有针对性地扩容、优化。结合楼主的经验和知识,本文做一个简单的总结,欢迎探讨。1、QPS保障目标...【详细内容】
2021-12-27  大数据架构师    Tags:架构   点击:(3)  评论:(0)  加入收藏
前言 单片机开发中,我们往往首先接触裸机系统,然后到RTOS,那么它们的软件架构是什么?这是我们开发人员必须认真考虑的问题。在实际项目中,首先选择软件架构是非常重要的,接下来我...【详细内容】
2021-12-23  正点原子原子哥    Tags:架构   点击:(7)  评论:(0)  加入收藏
现有数据架构难以支撑现代化应用的实现。 随着云计算产业的快速崛起,带动着各行各业开始自己的基于云的业务创新和信息架构现代化,云计算的可靠性、灵活性、按需计费的高性价...【详细内容】
2021-12-22    CSDN  Tags:数据架构   点击:(10)  评论:(0)  加入收藏
▶ 企业级项目结构封装释义 如果你刚毕业,作为Java新手程序员进入一家企业,拿到代码之后,你有什么感觉呢?如果你没有听过多模块、分布式这类的概念,那么多半会傻眼。为什么一个项...【详细内容】
2021-12-20  蜗牛学苑    Tags:微服务   点击:(8)  评论:(0)  加入收藏
我是一名程序员关注我们吧,我们会多多分享技术和资源。进来的朋友,可以多了解下青锋的产品,已开源多个产品的架构版本。Thymeleaf版(开源)1、采用技术: springboot、layui、Thymel...【详细内容】
2021-12-14  青锋爱编程    Tags:后台架构   点击:(20)  评论:(0)  加入收藏
在了解连接池之前,我们需要对长、短链接建立初步认识。我们都知道,网络通信大部分都是基于TCP/IP协议,数据传输之前,双方通过“三次握手”建立连接,当数据传输完成之后,又通过“四次挥手”释放连接,以下是“三次握手”与“四...【详细内容】
2021-12-14  架构即人生    Tags:连接池   点击:(16)  评论:(0)  加入收藏
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商...【详细内容】
2021-12-08  架构驿站    Tags:分布式系统   点击:(23)  评论:(0)  加入收藏
本系列为 Netty 学习笔记,本篇介绍总结Java NIO 网络编程。Netty 作为一个异步的、事件驱动的网络应用程序框架,也是基于NIO的客户、服务器端的编程框架。其对 Java NIO 底层...【详细内容】
2021-12-07  大数据架构师    Tags:Netty   点击:(16)  评论:(0)  加入收藏
前面谈过很多关于数字化转型,云原生,微服务方面的文章。虽然自己一直做大集团的SOA集成平台咨询规划和建设项目,但是当前传统企业数字化转型,国产化和自主可控,云原生,微服务是不...【详细内容】
2021-12-06  人月聊IT    Tags:架构   点击:(23)  评论:(0)  加入收藏
微服务看似是完美的解决方案。从理论上来说,微服务提高了开发速度,而且还可以单独扩展应用的某个部分。但实际上,微服务带有一定的隐形成本。我认为,没有亲自动手构建微服务的经历,就无法真正了解其复杂性。...【详细内容】
2021-11-26  GreekDataGuy  CSDN  Tags:单体应用   点击:(35)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条