很早之前就想寫一篇關於「規則引擎」的文章,但是一直苦於沒有時間。剛好最近給團隊小伙伴梳理了我設計的引擎的使用和原理,正好借此機會在此寫下我們的心得。
「規則引擎」系統一般而言,在風控中使用較多,但是經過調研,我們發現,其實在業務系統中,對於規則引擎系統的渴求度更大,甚至於,我在脈脈上都看到好幾個人在咨詢業務規則引擎系統應該如何設計和接入。
首先來聊一下痛點。為什么對於規則引擎系統的渴求度這么大?
缺點
業務條件繁雜
試想一下,或者說正是你所經歷的,在我們的業務邏輯中,有很多很多很多的業務條件判斷,而這些業務條件的修改往往又較為頻繁,如果你的項目部署還比較耗時,那么“開發五分鍾,部署一小時”的場景又會浮現。
業務配置修改頻繁
在我們的業務中,往往又有許多的業務配置嵌入其中,比如功能開關、白名單、黑名單等。而這些配置,如果你的項目有接入一些業務配置系統還好,如果沒有,那么又是需要發一波代碼。
業務咨詢
代碼對於我們的業務方來說是不可見的,遇到一些根本不是問題的問題時,總是會向技術人員咨詢。而你如果了解項目還好,但是一旦忘記,又需要去梳理一次業務邏輯。
幸福的家庭總是相似的,不幸的家庭卻各有各的不同。處理這些看似不經意的小問題,總是會不經意間打斷我們的思考。天下苦秦久已。
梳理一下,我們需要解決的事情至少有3點:
- 業務規則配置化。規則代碼的編寫,支持拔插和熱更新。
- 業務配置可視化。業務配置應交由業務方自行處理。
- 業務咨詢可見性。當業務遇到不清楚的問題時,可以非常清晰的在某個地方了解到原因所在。
經過調研,我們發現MVEL
手冊表達式非常適合我們去做這件事情。而支持MVEL
表達式的開源規則引擎系統中,我們認為easy-rules
更貼合我們的場景,一方面他支持MVEL
,另一方面,他也支持在Java
中自定義Rule
,另外,他還支持自定義規則引擎。
但是,僅靠easy-rules
並不能直接在使用生產環境中,我們需要針對自己的業務做一些調整,比如需要統一規則、需要統一屬性注入、需要統一返回結構等等。
我們大致畫了一下我們業務執行的主要流程。首先需要注意的是,在業務中,肯定會有不同場景的情況,因此我們需要做好場景區隔,我們不可能將所有的東西都在一個地方去執行。因此我設計的適合有些地方參考了Java I/O
這塊的設計思路,有一個EngineProviders
負責調度分發到不同的場景中。
每個場景都實現了統一的接口,而這個調度過程也是動態化的,盡可能較少我們開發同學所需要做的操作。
而在此之前,需要有一個統一的EngineService
來統一的去獲取我們配置的規則,去注入到場景中。同時,也需要把我們自定義的業務配置來注入到我們的數據源中。如下圖所示:
這里就是我們自定義的一些規則了,因為業務關系,打上了部分馬賽克,不過應該並不妨礙理解這里所要做的事情。
然而,我們在實際的業務中,還有很多地方都需要抽象的統一規則,因此,我們也可以借助easy-rules
提供的能力來幫助我們完成這種事情。
當然需要說明的是,還有一些細節沒有補充上去,比如構參builder
等,因為是根據我們業務自定義的,所以即使補充上去參考價值也不大。
最后還有一點,原因可視化的問題需要解決。其實這個相對而言就非常簡單了,我們僅需要在阻斷的地方記錄當時的參數,以及阻斷的規則,然后將其可視化,業務方自行查閱即可。
歡迎關注我的公眾號,每周至少一篇比較有深度的原創文章: