天天看點

「後端」一種通用的業務監控觸發方案設計

作者:架構思考

一、背景

業務監控是指通過技術手段監控業務代碼執行的最終結果或者狀态是否符合預期,實作業務監控主要分成兩步:一、在業務系統中選擇節點發送消息觸發業務監控;二、系統在接收到mq消息或者定時任務排程時,根據消息中或者任務中的業務資料查詢業務執行的結果或狀态并與業務預期的結果相對比。目前供銷系統的方案如下:

「後端」一種通用的業務監控觸發方案設計

由業務系統發送消息觸發規則中心的校驗任務,校驗邏輯和報警規則通過規則中心的groovy腳本代碼實作,該方案的缺點如下:

1.業務監控代碼摻雜在正常的業務代碼中,業務監控的代碼侵入性高;

2.業務監控消息觸發代碼可複用性極低,各個應用都要維護一套代碼,後期若要增加或維護某個功能時成本大;

3.增加業務監控的開發工作量,開發人員需要開發和維護與業務監控功能無關的代碼,如:消息觸發降級功能、性能監控、異步觸發等功能;

為解決上述問題,本文提出了一種通用的業務監控觸發方案。

二、方案介紹

  1. 通用mq消息體:
public class BusinessCheckMessage {
    /**
     * 監控類型
     */
    private String businessType;
    /**
     * 業務監控需要的參數
     */
    private Object data;
    /**
     * 業務方
     */
    private String businessSource;
    /**
     * 目前所屬的topic
     */
    private String topic;
}           

其中,

businessType用于區分業務監控的類型,如:終止合作、提單等;

data用于存儲和業務相關的關鍵資料,如訂單id、商家id等;

businessSource用于區分不同業務方的業務,如:萬商的提單、供銷的提單等;

topic用于隔離消息,如:業務監控任務執行快的可以用主題A、執行慢的的可以用主題B等;

2.自定義注解 + 切面

以供銷系統業務監控為例,接近50%的場景是将方法體中的參數作為業務資料來觸發業務監控,針對此場景,本文采用注解+切面解耦業務監控代碼和正常業務代碼,降低業務監控代碼對正常的業務代碼的侵入,其中自定義注解負責擷取業務監控需要用到的方法入參中的相關資料,切面負責組裝通用mq資料模型并完成消息的發送。自定義注解定義如下:

public @interface BusinessCheckPoint {
    /**     
     * 業務監控類型     
     */    
   String businessType();    
   /**     
    * 業務方     
    */    
   String businessSource();    
   /**     
    * 要發送的消息的topic     
    */    
   String businessTopic();    
   /**     
    * 方法參數的第幾個參數作為消息内容,從0開始     
   */    
   int dataIndex();    
   /**     
    * 在執行業務流程前發送消息     
    * 預設在業務流程執行後發送消息     
    */    
   boolean beforeOperate() default false;
}           

其中,

businesstype用于擷取業務監控類型;

businessSource用于擷取業務方;

businessTopic用于擷取目前要發送的消息主體;

dataIndex用于擷取方法體參數中的資料,從0開始;

beforeOperate用于擷取消息發送的時間,在業務流程執行後發送消息還是業務流程執行前發消息;

3.侵入式觸發業務監控

考慮到業務系統可能會在複雜場景下觸發業務監控,本文也提供了通用的解決方案,具體如何使用見下一章節的實戰介紹。

三、實戰介紹

1.引入依賴

<dependency>    
    <groupId>com.jd</groupId>    
    <artifactId>business.check</artifactId>   
    <version>1.0.0</version>
</dependency>           

2.初始化切面

<bean id="businessCheckAspect" class="com.jd.gmall.monitor.aspect.BusinessCheckAspect"/>           

3.Producer及線程池指派

<bean id="businessCheckHandler" class="com.jd.gmall.monitor.service.impl.BusinessCheckHandlerImpl">    
    <property name="messageProducerMap">        
        <map>            
            <entry key="gx_bussiness_check" value-ref="businessCheckProducer" />        
        </map>    
    </property>    
    <property name="commonExecutor" ref="asyncTaskThreadPoolTaskExecutor"/>
</bean>           

其中,

messageProducerMap類型為Map<String, Producer>,用于指定topic對應的Producer;

commonExecutor用于指定異步發送消息時用到的線程池(建議自行建立線程池);

4.業務監控消息發送

場景一:

簡單場景下可使用自定義注解來發送消息,如下所示

「後端」一種通用的業務監控觸發方案設計

業務監控類型 = “100”

消息主題 = “gx_bussiness_check”

業務方 = “ws”

消息體中的業務資料data = req

場景二:

複雜場景下,可在服務中注入sdk中的消息發送服務,如下所示

「後端」一種通用的業務監控觸發方案設計
「後端」一種通用的業務監控觸發方案設計

場景二與場景一發送的消息内容一緻。

5.業務監控降級不發送消息

sdk中的類BusinessCheckHandlerImpl中定義了控制降級的方法:

public static void setBusinessCheckSwitch(boolean businessCheckSwitch) {            
    BusinessCheckHandlerImpl.businessCheckSwitch = businessCheckSwitch;
}           

此處給出了通過ducc控制降級的方法:

@LafValue("business.check.switch")
public void setBusinessCheckSwitch(boolean switch) {   
  BusinessCheckHandlerImpl.setBusinessCheckSwitch(b);
}           

switch:true,開啟消息發送;false,降級

文章來源:京東零售_胡飛_https://juejin.cn/post/7233455566051229752

繼續閱讀