<div class="content-detail markdown-body" data-spm-anchor-id="a2c4e.11153940.blogcont74594.i8.6b9315dactpjMr">css
<p>規則引擎由推理引擎發展而來,是一種嵌入在應用程序中的組件,實現了將業務決策從應用程序代碼中分離出來,並使用預約義的語義模塊編寫業務決策。<br>規則引擎具體執行能夠分爲接受數據輸入,解釋業務規則,根據業務規則作出業務決策幾個過程。<br>使用規則引擎能夠把複雜、冗餘的業務規則同整個支撐系統分離開,作到架構的可複用移植。</p> <p></p> <h2 id="1">規則引擎的應用</h2> <p>相對於業務系統,規則引擎能夠認爲是一個獨立於業務系統的模塊,負責一些規則的計算等。<br>通常來講,規則引擎主要應用在下面的場景中:</p> <ul> <li data-spm-anchor-id="a2c4e.11153940.blogcont74594.i0.6b9315dactpjMr">風控模型配置,風控是規則引擎</li> <li data-spm-anchor-id="a2c4e.11153940.blogcont74594.i1.6b9315dactpjMr">用戶積分等配置,如平常操做引發積分變化等</li> <li data-spm-anchor-id="a2c4e.11153940.blogcont74594.i2.6b9315dactpjMr">簡單的離線計算,各種數據量比較小的統計等</li> </ul> <h3 id="2">經常使用規則引擎的選型</h3> <p>目前的規則引擎系統中,使用較多的開源規則引擎是Drools,另外還有商用的規則管理系統BRMS是ILOG JRules。</p> <h3 id="3">Drools</h3> <p data-spm-anchor-id="a2c4e.11153940.blogcont74594.i3.6b9315dactpjMr">Drools是一個基於Java的開源規則引擎,能夠將複雜多變的規則從硬編碼中解放出來,以規則腳本的形式存放在文件中,使得規則的變動不須要修正代碼重啓機器就能夠當即在線上環境生效。</p> <p>目前版本是5.0.1,Drools從5.0後分爲四個模塊:</p> <ul> <li>Drools Guvnor (BRMS/BPMS)</li> <li>Drools Expert (rule engine)</li> <li>Drools Flow (process/workflow)</li> <li>Drools Fusion (cep/temporal reasoning)</li> </ul> <p><a href="https://github.com/kiegroup/drools" data-spm-anchor-id="a2c4e.11153940.blogcont74594.11">drools代碼地址</a></p> <p>[drools應用文檔](<a href="https://github.com/kiegroup/droolsjbpm-build-bootstrap/blob/master/README.md" data-spm-anchor-id="a2c4e.11153940.blogcont74594.12">https://github.com/kiegroup/droolsjbpm-build-bootstrap/blob/master/README.md</a><br>)</p> <h3 id="4">Ilog JRules</h3> <p>Ilog Jrules是完整的業務規則管理系統(BRMS),它提供了對整個企業業務規則進行建模、編寫、測試、部署和維護所必需的全部工具。</p> <p>Ilog Jrules主要包括如下4個組件:</p> <ul> <li data-spm-anchor-id="a2c4e.11153940.blogcont74594.i4.6b9315dactpjMr">Rule Studio(RS) 面向開發人員使用的開發環境,用於規則的建模和編寫</li> <li data-spm-anchor-id="a2c4e.11153940.blogcont74594.i5.6b9315dactpjMr">Rule Scenario Manager 規則測試工具</li> <li data-spm-anchor-id="a2c4e.11153940.blogcont74594.i6.6b9315dactpjMr">Rule Team Server(RTS) 基於Web的管理環境,面向業務人員使用,用於規則發佈、管理、存儲</li> <li>Rule Execution Server(RES) 面向運維人員使用,用於規則執行、監控</li> </ul> <p>[Ilog Jrules主頁](<a href="https://www-01.ibm.com/software/integration/business-rule-management/jrules-family/" data-spm-anchor-id="a2c4e.11153940.blogcont74594.13">https://www-01.ibm.com/software/integration/business-rule-management/jrules-family/</a><br>)</p> <p>這兩款規則引擎設計和實現都比較複雜,學習成本高,適用於大型應用系統。</p> <h3 id="5">Easy Rules</h3> <p data-spm-anchor-id="a2c4e.11153940.blogcont74594.i7.6b9315dactpjMr">Easy Rules是我偶然間看到的一個規則引擎實現,相比Drools等企業級規則引擎,Easy Rules的應用很是簡單,學習成本低,容易上手。<br>下面重點介紹這款輕量級的規則引擎 Easy Rules。</p> <p></p> <h2 id="6">輕量級規則引擎Easy Rules</h2> <p>Easy Rules官方主頁:<a href="http://www.easyrules.org/?spm=a2c4e.11153940.blogcont74594.14.6b9315dactpjMr" data-spm-anchor-id="a2c4e.11153940.blogcont74594.14">http://www.easyrules.org/</a></p> <p>Easy Rules提供如下功能:</p> <ul> <li>輕量級框架和易於學習的API</li> <li>基於POJO的開發</li> <li>經過高效的抽象來定義業務規則並輕鬆應用它們</li> <li>支持建立複合規則</li> </ul> <h3 id="7">Easy Rules的應用</h3> <p>Easy rules的工程能夠從Github下載,構建須要Maven支持。</p> <pre><code class="hljs ruby">$ git clone <span class="hljs-symbol">https:</span>/<span class="hljs-regexp">/github.com/</span>EasyRules/easyrules.git $ cd easyrules $ mvn install </code></pre> <p>Easy Rules打包後是一個單獨的jar,使用時須要添加相關文件到工程中,或者添加Maven依賴:</p> <pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">dependency</span>></span> <span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>org.easyrules<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span> <span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>easyrules-core<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span> <span class="hljs-tag"><<span class="hljs-name">version</span>></span>2.4.0<span class="hljs-tag"></<span class="hljs-name">version</span>></span> <span class="hljs-tag"></<span class="hljs-name">dependency</span>></span> </code></pre> <h3 id="8">配置你的業務規則</h3> <p>大多數業務規則能夠表示爲如下定義:</p> <ul> <li>名稱:一種惟一的規則名稱</li> <li>描述:對規則的簡要描述</li> <li>優先級:相對於其餘規則的優先級</li> <li>條件:設置規則執行時須要知足的條件</li> <li>操做:設置的條件知足時執行的操做</li> </ul> <p>咱們能夠經過擴展Easy Rules提供的Rule interface來定義規則,或者經過註解,定義本身的規則類。</p> <p>下面是內置的Rule接口:</p> <pre><code class="hljs java"><span class="hljs-keyword">package</span> org.easyrules.api;java
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Rule</span> </span>{git
<span class="hljs-comment">/** * 這個方法定義了規則執行的條件 * <span class="hljs-doctag">@return</span> true if the rule should be applied, false else */</span> <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">evaluate</span><span class="hljs-params">()</span></span>; <span class="hljs-comment">/** * 這個方法定義了規則執行的具體動做 * <span class="hljs-doctag">@throws</span> Exception if an error occurs */</span> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">execute</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception</span>; <span class="hljs-comment">//Getters and setters for rule name,</span> <span class="hljs-comment">//description and priority omitted.</span>
} </code></pre>github
<h3 id="9">建立規則引擎</h3> <p>Easy Rules的引擎實例會維護一個不一樣規則的註冊空間,每一個Engine能夠被視爲一個單獨的名稱空間。<br>多條規則將會按照他們的天然順序去執行,也就是默認的優先級。</p> <p>要建立一個規則引擎和註冊規則,能夠使用下面的靜態方法:</p> <pre><code class="hljs">RulesEngineBuilder.aNewEngineBuilder(): RulesEngine rulesEngine = aNewEngineBuilder().build(); rulesEngine.registerRule(myRule);</code></pre> <p>執行下面的操做啓動規則執行:</p> <pre><code class="hljs css"><span class="hljs-selector-tag">rulesEngine</span><span class="hljs-selector-class">.fireRules</span>();</code></pre> <p></p> <h3 id="10">Easy Rules應用實例</h3> <p>下面經過一個簡單的Hello World示例來展現Easy Rules的具體應用。</p> <p>經過註解建立一個具體的規則類:</p> <pre><code class="hljs java"><span class="hljs-meta">@Rule</span>(name = <span class="hljs-string">"Hello World rule"</span>, description = <span class="hljs-string">"Say Hello to duke's friends only"</span>) <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HelloWorldRule</span> </span>{bootstrap
<span class="hljs-comment">/** * The user input which represents the data * that the rule will operate on. */</span> <span class="hljs-keyword">private</span> String input; <span class="hljs-meta">@Condition</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">checkInput</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">//The rule should be applied only if</span> <span class="hljs-comment">//the user's response is yes (duke friend)</span> <span class="hljs-keyword">return</span> input.equalsIgnoreCase(<span class="hljs-string">"yes"</span>); } <span class="hljs-meta">@Action</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHelloToDukeFriend</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{ <span class="hljs-comment">//When rule conditions are satisfied,</span> <span class="hljs-comment">//prints 'Hello duke's friend!' to the console</span> System.out.println(<span class="hljs-string">"Hello duke's friend!"</span>); } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setInput</span><span class="hljs-params">(String input)</span> </span>{ <span class="hljs-keyword">this</span>.input = input; }
} </code></pre>api
<p>接下來建立一個規則引擎的實例,註冊而且啓動這個規則:</p> <pre><code class="hljs cs"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Launcher</span> {ruby
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>) </span>{ Scanner scanner = <span class="hljs-keyword">new</span> Scanner(System.<span class="hljs-keyword">in</span>); System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Are you a friend of duke?[yes/no]:"</span>); String input = scanner.nextLine(); <span class="hljs-comment">/** * Declare the rule */</span> HelloWorldRule helloWorldRule = <span class="hljs-keyword">new</span> HelloWorldRule(); <span class="hljs-comment">/** * Set business data to operate on */</span> helloWorldRule.setInput(input.trim()); <span class="hljs-comment">/** * Create a rules engine and register the business rule */</span> RulesEngine rulesEngine = aNewRulesEngine().build(); rulesEngine.registerRule(helloWorldRule); <span class="hljs-comment">/** * Fire rules */</span> rulesEngine.fireRules(); }
} </code></pre>markdown
<p>規則啓動後會經過一個簡單的條件判斷(控制檯輸入),而後執行接下來的動做(輸出規則信息)。</p> <p>除了規則引擎基礎的規則執行功能, Easy Rules還支持監聽規則執行狀況,爲規則執行配置調度器,<br>集成Spring等功能。</p> <h4 id="11">關於規則引擎的選型和簡單應用就介紹到這裏,除了風控等大型的應用系統,一些獨立的小型產品需求中,能夠合理應用規則引擎實現業務與規則的分離,下降系統間耦合,上面介紹的Easy Rules就是一個不錯的選擇。</h4>架構
<!-- 登陸查看 begin --> <!-- 登陸查看 end --> </div>