一、背景

业务监控是指通过技术手段监控业务代码执行的最终后果或者状态是否合乎预期,实现业务监控次要分成两步:一、在业务零碎中抉择节点发送音讯触发业务监控;二、零碎在接管到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,降级

作者:京东批发 胡飞

内容起源:京东云开发者社区