应用性能监控

使用APM监控异步任务

2024-07-16 06:25:13

对于通过Spring @Async标签或者Java Executors实现的异步任务,APM默认支持对其进行监控。若您的异步任务出现接口超时等异常,可以通过调用链路查看异步任务上下游以便及时处理潜在问题。

前置条件

该功能要求APM探针版本为公测版本v1.1.1及以上。

方式一:默认支持Spring @Async标签

APM默认支持监控使用Spring @Async标签实现的异步任务。对于下列Spring框架中默认的Executor和Task,APM会自动完成增强:

● Executor

○ org.springframework.scheduling.concurrent.ConcurrentTaskExecutor

○ org.springframework.core.task.SimpleAsyncTaskExecutor

○ org.springframework.scheduling.quartz.SimpleThreadPoolTaskExecutor

○ org.springframework.core.task.support.TaskExecutorAdapter

○ org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

○ org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler

○ org.springframework.jca.work.WorkManagerTaskExecutor

○ org.springframework.scheduling.commonj.WorkManagerTaskExecutor

● Task:org.springframework.aop.interceptor.AsyncExecutionInterceptor$1

○ org.springframework.aop.interceptor.AsyncExecutionInterceptor$$Lambda$

方式二:通过增强Runnable接口、Callable接口和Executor

当您没有使用spring框架时,上述场景无法满足需求时,也可以通过自动增强Runnable接口、Callable接口和Executor,在异步线程中完成调用链串联,实现异步任务监控。

1增强Runnable接口和Callable接口

public class MyRunnable implements Runnable {
 
     @Override
     public void run() {
         // 在这里定义需要在新线程中执行的任务逻辑
         for (int i = 0; i < 5; i++) {
             System.out.println("Thread ID: " + Thread.currentThread().getId() + " - Count: " + i);
         }
     }
 
     public static void main(String[] args) {
         // 创建一个Runnable实例
         Runnable myRunnable = new MyRunnable();
 
         // 创建线程并将Runnable实例传递给线程
         Thread thread1 = new Thread(myRunnable);
         Thread thread2 = new Thread(myRunnable);
 
         // 启动线程
         thread1.start();
         thread2.start();
     }
 }

2、  增强Executor

import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 
 public class ExecutorDemo {
 
     public static void main(String[] args) {
         // 创建一个线程池,这里使用固定大小的线程池
         Executor executor = Executors.newFixedThreadPool(3);
 
         // 提交任务给线程池执行
         for (int i = 0; i < 5; i++) {
             final int taskId = i;
             executor.execute(() -> {
                 // 在这里定义需要执行的任务逻辑
                 System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
             });
         }
 
         // 关闭线程池(通常在应用程序退出时执行)
         if (executor instanceof java.util.concurrent.ExecutorService) {
             ((java.util.concurrent.ExecutorService) executor).shutdown();
         }
     }
 }

执行结果

配置完成后,您可以在调用链路详情页查看异步任务的调用链详情。具体详情。


fkBZ7mFpQCez