[调优]埋点&MQ处理优化

从业务方法相关性上看,MQ是业务方法正相关的,埋点和业务方法是不相关的。

从方法执行顺序上看,目前我们处理MQ发送、埋点记录都是嵌套在方法体中的,这种侵入强对于正常业务方法不友好,容易造成代码逻辑混乱,而且是在方法主线程中作为业务方法的一份子一同处理执行的,尽管埋点记录、MQ发送调用的耗时并不会给业务方法带来根本性影响,但是由于是出现在主线程中执行所以一旦出现异常,业务方法是走不通的,让非业务方法影响业务方法这本身就是一个不可接受的处理方式,所以需要优化,尽管99.999%甚至100%的时间都不会出现问题,但并不代表它永远不会出现问题。

埋点方法、MQ方法不太适合做切面,因为触发点都是在业务方法体的某一步触发的,可以优化成类似下面这样的,写个简单的DEMO,模拟下

@Test
public void async() throws InterruptedException {
    //主线程执行部分-业务方法开始
    System.out.printf("%s BEGIN-async_mq \n",Thread.currentThread().getName());
 
    //子线程执行部分
    taskExecutor.submit(() -> {
        try {
            System.out.printf("%s 发送MQ开始 \n", Thread.currentThread().getName());
            //模拟MQ处理
            Thread.sleep(1000);
            System.out.printf("%s 发送MQ结束 \n", Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    taskExecutor.submit(() -> {
        try {
            System.out.printf("%s 埋点开始 \n", Thread.currentThread().getName());
            //模拟埋点处理
            Thread.sleep(1000);
            System.out.printf("%s 埋点结束 \n", Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
     
    //主线程执行部分-业务方法结束
    System.out.printf("%s END-async_mq \n",Thread.currentThread().getName());
 
    //这里可以等等子线程的日志输出
    //Thread.sleep(3000);
}
 
 
 
 
日志输出类似这样的,主线程执行完直接返回结果了,子线程慢慢处理MQ、埋点,子线程可以封装下,比如异常捕获不要影响主线程,但是要做报警让研发同学可以感知进行处理
main BEGIN-async_mq
main END-async_mq
 
 
taskExecutor-1 发送MQ开始
taskExecutor-2 埋点开始
taskExecutor-1 发送MQ结束
taskExecutor-2 埋点结束
  • 如果不想自己写,其实也可以借助Spring的Listener&Event事件异步驱动
  • 虽然优化并不起眼,但优化都是一步步累积的,量变引起质变,好的东西是,不好的东西也是。
posted @ 2021-02-22 14:11  大摩羯先生  阅读(25)  评论(0编辑  收藏  举报