亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

背景

考拉安全部技術(shù)這塊目前主要負責(zé)兩塊業(yè)務(wù):一個是內(nèi)審,主要是通過敏感日志管理平臺搜集考拉所有后臺系統(tǒng)的操作日志,數(shù)據(jù)導(dǎo)入到es后,結(jié)合storm進行實時計算,主要有行為查詢、數(shù)據(jù)監(jiān)控、事件追溯、風(fēng)險大盤等功能;一個是業(yè)務(wù)風(fēng)控,主要是下單、支付、優(yōu)惠券、紅包、簽到等行為的風(fēng)險控制,對抗的風(fēng)險行為包括黃牛刷單、惡意占用庫存、機器領(lǐng)券、擼羊毛等。這兩塊業(yè)務(wù)其實有一個共通點,就是有大量需要進行規(guī)則決策的場景,比如內(nèi)審中需要進行實時監(jiān)控,當(dāng)同一個人在一天時間內(nèi)的導(dǎo)出操作超過多少次后進行告警,當(dāng)?shù)卿洉r不是常用地登錄并且設(shè)備指紋不是該賬號使用過的設(shè)備指紋時告警。而在業(yè)務(wù)風(fēng)控中需要使用到規(guī)則決策的場景更多,由于涉及規(guī)則的保密性,這里就不展開了。總之,基于這個出發(fā)點,安全部決定開發(fā)出一個通用的規(guī)則引擎平臺,來滿足以上場景。

寫在前面

在給出整體架構(gòu)前,想跟大家聊聊關(guān)于架構(gòu)的一些想法。目前架構(gòu)上的分層設(shè)計思想已經(jīng)深入人心,大家都知道要分成controller,server,dao等,是因為我們剛接觸到編碼的時候,mvc的模型已經(jīng)大行其道,早期的jsp里面包含大量業(yè)務(wù)代碼邏輯的方式已經(jīng)基本絕跡。但是這并不是一種面向?qū)ο蟮乃伎挤绞剑覀兪且砸环N面向過程的思維去編程。舉個簡單例子,我們要實現(xiàn)一個網(wǎng)銀賬戶之間轉(zhuǎn)賬的需求,往往會是下面這種實現(xiàn)方式:

  1. 設(shè)計一個賬戶交易服務(wù)接口AccountingService,設(shè)計一個服務(wù)方法transfer(),并提供一個具體實現(xiàn)類AccountingServiceImpl,所有賬戶交易業(yè)務(wù)的業(yè)務(wù)邏輯都置于該服務(wù)類中。
  2. 提供一個AccountInfo和一個Account,前者是一個用于與展示層交換賬戶數(shù)據(jù)的賬戶數(shù)據(jù)傳輸對象,后者是一個賬戶實體(相當(dāng)于一個EntityBean),這兩個對象都是普通的JAVABean,具有相關(guān)屬性和簡單的get/set方法。
  3. 然后在transfer方法中,首先獲取A賬戶的余額,判斷是否大于轉(zhuǎn)賬的金額,如果大于則扣減A賬戶的余額,并增加對應(yīng)的金額到B賬戶。

這種設(shè)計在需求簡單的情況下看上去沒啥問題,但是當(dāng)需求變得復(fù)雜后,會導(dǎo)致代碼變得越來越難以維護,整個架構(gòu)也會變的腐爛。比如現(xiàn)在需要增加賬戶的信用等級,不同等級的賬戶每筆轉(zhuǎn)賬的最大金額不同,那么我們就需要在service里面加上這個邏輯。后來又需要記錄轉(zhuǎn)賬明細,我們又需要在service里面增加相應(yīng)的代碼邏輯。最后service代碼會由于需求的不斷變化變得越來越長,最終變成別人眼中的“祖?zhèn)鞔a”。導(dǎo)致這個問題的根源,我認為就是我們使用的是一種面向過程的編程思想。那么如何去解決這種問題呢?主要還是思維方式上需要改變,我們需要一種真正的面向?qū)ο蟮乃季S方式。比如一個“人”,除了有id、姓名、性別這些屬性外,還應(yīng)該有“走路”、“吃飯”等這些行為,這些行為是天然屬于“人”這個實體的,而我們定義的bean都是一種“失血模型”,只有g(shù)et/set等簡單方法,所有的行為邏輯全部上升到了service層,這就導(dǎo)致了service層過于臃腫,并且很難復(fù)用已有的邏輯,最后形成了各個service之間錯綜復(fù)雜的關(guān)聯(lián)關(guān)系,在做服務(wù)拆分的時候,很難劃清業(yè)務(wù)邊界,導(dǎo)致服務(wù)化進程陷入泥潭。

對應(yīng)上面的問題,我們可以在Account這個實體中加入本應(yīng)該就屬于這個實體的行為,比如借記、貸記、轉(zhuǎn)賬等。每一筆轉(zhuǎn)賬都對應(yīng)著一筆交易明細,我們根據(jù)交易明細可以計算出賬戶的余額,這個是一個潛在的業(yè)務(wù)規(guī)則,這種業(yè)務(wù)規(guī)則都需要交由實體本身來維護。另外新增賬戶信用實體,提供賬戶單筆轉(zhuǎn)賬的最大金額計算邏輯。這樣我們就把原本全部在service里面的邏輯劃入到不同的負責(zé)相關(guān)職責(zé)的“領(lǐng)域?qū)ο?rdquo;當(dāng)中了,service的邏輯變得非常清楚明了,想實現(xiàn)A給B轉(zhuǎn)賬,直接獲取A實體,然后調(diào)用A實體中的轉(zhuǎn)賬方法即可。service將不再關(guān)注轉(zhuǎn)賬的細節(jié),只負責(zé)將相關(guān)的實體組織起來,完成復(fù)雜的業(yè)務(wù)邏輯處理。

上面的這種架構(gòu)設(shè)計方式,其實就是一種典型的“領(lǐng)域驅(qū)動設(shè)計(DDD)”思想,在這里就不展開說明了(主要是自己理解的還不夠深入,怕誤導(dǎo)大家了)。DDD也是目前非常熱門的一種架構(gòu)設(shè)計思想了,它不能減少你的代碼量,但是能使你的代碼具有很高的內(nèi)聚性,當(dāng)你的項目變得越來越復(fù)雜時,能保持架構(gòu)的穩(wěn)定而不至于過快的腐爛掉,不了解的同學(xué)可以查看相關(guān)資料。要說明的是,沒有一種架構(gòu)設(shè)計是萬能的、是能解決所有問題的,我們需要做的是吸收好的架構(gòu)設(shè)計思維方式,真正架構(gòu)落地時還是需要根據(jù)實際情況選擇合適的架構(gòu)。

整體架構(gòu)設(shè)計

上面說了些架構(gòu)設(shè)計方面的想法,現(xiàn)在我們回到規(guī)則引擎平臺本身。我們抽象出了四個分層,從上到下分別為:服務(wù)層、引擎層、計算層和存儲層,整個邏輯層架構(gòu)見下圖:

網(wǎng)易考拉規(guī)則引擎平臺架構(gòu)設(shè)計與實踐

 

  • 服務(wù)層:服務(wù)層主要是對外提供服務(wù)的入口層,提供的服務(wù)包括數(shù)據(jù)分析、風(fēng)險檢測、業(yè)務(wù)決策等,所有的服務(wù)全部都是通過數(shù)據(jù)接入模塊接入數(shù)據(jù),具體后面講
  • 引擎層:引擎層是整個平臺的核心,主要包括了執(zhí)行規(guī)則的規(guī)則引擎、還原事件現(xiàn)場和聚合查詢分析的查詢引擎以及模型預(yù)測的模型引擎
  • 計算層:計算層主要包括了指標計算模塊和模型訓(xùn)練模塊。指標會在規(guī)則引擎中配置規(guī)則時使用到,而模型訓(xùn)練則是為模型預(yù)測做準備
  • 存儲層:存儲層包括了指標計算結(jié)果的存儲、事件信息詳情的存儲以及模型樣本、模型文件的存儲

在各個分層的邏輯架構(gòu)劃定后,我們就可以開始分析整個平臺的業(yè)務(wù)功能模塊。主要包括了事件接入模塊、指標計算模塊、規(guī)則引擎模塊、運營中心模塊,整個業(yè)務(wù)架構(gòu)如下圖:

網(wǎng)易考拉規(guī)則引擎平臺架構(gòu)設(shè)計與實踐

 

1.事件接入中心

事件接入中心主要包括事件接入模塊和數(shù)據(jù)管理模塊。數(shù)據(jù)接入模塊是整個規(guī)則引擎的數(shù)據(jù)流入口,所有的業(yè)務(wù)方都是通過這個模塊接入到平臺中來。提供了實時(dubbo)、準實時(kafka)和離線(hive)三種數(shù)據(jù)接入方式。數(shù)據(jù)管理模塊主要是進行事件的元數(shù)據(jù)管理、標準化接入數(shù)據(jù)、補全必要的字段,如下圖:

網(wǎng)易考拉規(guī)則引擎平臺架構(gòu)設(shè)計與實踐

 

2.指標計算模塊

指標計算模塊主要是進行指標計算。一個指標由主維度、從維度、時間窗口等組成,其中主維度至少有一個,從維度最多有一個。如下圖:

網(wǎng)易考拉規(guī)則引擎平臺架構(gòu)設(shè)計與實踐

 

舉個例子,若有這樣一個指標:“最近10分鐘,同一個賬號在同一個商家的下單金額”,那么主維度就是下單賬號+商家id,從維度就是訂單金額。可以看到,這里的主維度相當(dāng)于sql里面的group by,從維度相當(dāng)于count,數(shù)值累加相當(dāng)于sum。從關(guān)于指標計算,有幾點說明下:

  1. key的構(gòu)成。我們的指標存儲是用的redis,那么這里會涉及到一個key該如何構(gòu)建的問題。我們目前的做法是:key=指標id+版本號+主維度值+時間間隔序號。
    • 指標id就是指標的唯一標示;
    • 版本號是指標對象的版本,每次更新完指標都會更新對應(yīng)的版本號,這樣可以讓就的指標一次全部失效;
    • 主維度值是指當(dāng)前事件對象中,主維度字段對應(yīng)的值,比如一個下單事件,主維度是用戶賬號,那么這里就是對應(yīng)的類似[email protected],如果有多個主維度則需要全部組裝上去;
    • 如果主維度的值出現(xiàn)中文,這樣直接拼接在key里面會有問題,可以采用轉(zhuǎn)義或者md5的方式進行。
    • 時間間隔序號是指當(dāng)前時間減去指標最后更新時間,得到的差值再除以采樣周期,得到一個序號。這么做主要是為了實現(xiàn)指標的滑動窗口計算,下面會講
  1. 滑動窗口計算。比如我們的指標是最近10分鐘的同一用戶的下單量,那么我們就需要實現(xiàn)一種類似的滑動窗口算法,以便任何時候都能拿到“最近10分鐘”的數(shù)據(jù)。這里我們采用的是一種簡單的算法:創(chuàng)建指標時,指定好采樣次數(shù)。比如要獲取“最近10分鐘”的數(shù)據(jù),采樣次數(shù)設(shè)置成30次,這樣我們會把每隔20秒的數(shù)據(jù)會放入一個key里面。每次一個下單事件過來時,計算出時間間隔序號(見第1點),然后組裝好key之后看該key是否存在,存在則進行累計,否則往redis中添加該key。
  2. 如何批量獲取key。每次獲取指標值時,我們都是先計算出需要的key集合(比如我要獲取“單個賬號最近10分鐘的下單量”,我可能需要獲取30個key,因為每個key的跨度是20s),然后獲取到對應(yīng)的value集合,再進行累加。而實際上我們只是需要累加后的值,這里可以通過redis+lua腳本進行優(yōu)化,腳本里面直接根據(jù)key集合獲取value后進行累加然后返回給客戶端,這樣就較少了每次響應(yīng)的數(shù)據(jù)量。
  3. 如何保證指標的計算結(jié)果不丟失?目前的指標是存儲在redis里面的,后來會切到solo-ldb,ldb提供了持久化的存儲引擎,可以保證數(shù)據(jù)不丟失。

3.規(guī)則引擎模塊

計劃開始做規(guī)則引擎時進行過調(diào)研,發(fā)現(xiàn)很多類似的平臺都會使用drools。而我們從一開始就放棄了drools而全部使用groovy腳本實現(xiàn),主要是有以下幾點考慮:

  • drools相對來說有點重,而且它的規(guī)則語言不管對于開發(fā)還是運營來說都有學(xué)習(xí)成本
  • drools使用起來沒有g(shù)roovy腳本靈活。groovy可以和spring完美結(jié)合,并且可以自定義各種組件實現(xiàn)插件化開發(fā)。
  • 當(dāng)規(guī)則集變得復(fù)雜起來時,使用drools管理起來有點力不從心。

當(dāng)然還有另外一種方式是將drools和groovy結(jié)合起來,綜合雙方的優(yōu)點,也是一種不錯的選擇,大家可以嘗試一下。

規(guī)則引擎模塊是整個平臺的核心,我們將整個模塊分成了以下幾個部分:

網(wǎng)易考拉規(guī)則引擎平臺架構(gòu)設(shè)計與實踐

 

規(guī)則引擎在設(shè)計中也碰到了一些問題,這里給大家分享下一些心得:

  • 使用插件的方式加載各種組件到上下文中,極大的方便了功能開發(fā)的靈活性。
  • 使用預(yù)加載的方式加載已有的規(guī)則,并將加載后的對象緩存起來,每次規(guī)則變更時重新load整條規(guī)則,極大的提升了引擎的執(zhí)行效率
  • 計數(shù)器引入AtomicLongFieldUpdater工具類,來減少計數(shù)器的內(nèi)存消耗
  • 靈活的上下文使用方式,方便定制規(guī)則執(zhí)行的流程(規(guī)則執(zhí)行順序、同步異步執(zhí)行、跳過某些規(guī)則、規(guī)則集短路等),靈活定義返回結(jié)果(可以返回整個上下文,可以返回每條規(guī)則的結(jié)果,也可以返回最后一條規(guī)則的結(jié)果),這些都可以通過設(shè)置上下文來實現(xiàn)。
  • groovy的方法查找策略,默認是從metaClass里面查找,再從上下文里找,為了提升性能,我們重寫了metaClass,修改了這個查詢邏輯:先從上下文里找,再從metaClass里面找。

規(guī)則配置如下圖所示:

網(wǎng)易考拉規(guī)則引擎平臺架構(gòu)設(shè)計與實踐

 

未來規(guī)劃

后面規(guī)則引擎平臺主要會圍繞下面幾點來做:

  1. 指標存儲計劃從redis切換到hbase。目前的指標計算方式會導(dǎo)致緩存key的暴漲,獲取一個指標值可能需要N個key來做累加,而換成hbase之后,一個指標就只需要一條記錄來維護,使用hbase的列族來實現(xiàn)滑動窗口的計算。
  2. 規(guī)則的灰度上線。當(dāng)一條新規(guī)則創(chuàng)建后,如果不進行灰度的測試,直接上線是可能會帶來災(zāi)難的。后面再規(guī)則上線流程中新增灰度上線環(huán)節(jié),整個引擎會根據(jù)配置的灰度比例,復(fù)制一定的流量到灰度規(guī)則中,并對灰度規(guī)則的效果進行展示,達到預(yù)期效果并穩(wěn)定后才能審批上線。
  3. 事件接入的自動化。dubbo這塊可以采用泛化調(diào)用,http接口需要統(tǒng)一調(diào)用標準,消息需要統(tǒng)一格式。有了統(tǒng)一的標準就可以實現(xiàn)事件自動接入而不需要修改代碼上線,這樣也可以保證整個引擎的穩(wěn)定性。
  4. 模型生命周期管理。目前模型這塊都是通過在猛犸平臺上提交jar包的方式,離線跑一個model出來,沒有一個統(tǒng)一的平臺去管控整個模型的生命周期。現(xiàn)在杭研已經(jīng)有類似的平臺了,后續(xù)需要考慮如何介入。
  5. 數(shù)據(jù)展示優(yōu)化。現(xiàn)在整個平臺的數(shù)字化做的比較弱,沒法形成數(shù)據(jù)驅(qū)動業(yè)務(wù)。而風(fēng)控的運營往往是需要大量的數(shù)據(jù)去驅(qū)動規(guī)則的優(yōu)化的,比如規(guī)則閾值的調(diào)試、規(guī)則命中率、風(fēng)險大盤等都需要大量數(shù)據(jù)的支撐。

分享到:
標簽:架構(gòu) 設(shè)計
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定