skywalking
的线程池支持插件,可以支持lamdba
表达式
问: skywalking
已经提供了多线程的支持插件,为什么还要自己造轮子
答:官方提供的插件,切入点是Runnable
的实现类,那如果直接写的lamdba
表达式,就无法织入。
本仓库提供的插件是基于skywalking7.0
的版本,如果你用的是该版本,可以在本仓库目录/chy/plugins
下载作者已经编译好的插件。
注意
: 因为要织入ThreadPool
,作者这里稍稍修改了apm-agent
,所以要使用我提供的apm-agent.jar
作为agent
的入口包
也可以在/chy/
目录下找到。
把apm-chy-threading-plugin-7.0.0.jar
放入plugins
文件夹,使用我提供的apm-agent.jar
就能能够正常工作了
如果需要二次修改那可以使用手动编译
clone
本仓库到本地后,使用maven
命令编译打包
mvn clean package -DskipTests -Dcheckstyle.skip=true
运行上面maven命令后,也是在项目目录下的chy
文件中可以找到编译后的jar
@GetMapping("/ajax/{setId}/async")
public List<DoctorListVO> getDoctorListasync(@PathVariable Integer setId) throws ExecutionException, InterruptedException {
//线程池访问
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<List<DoctorListVO>> submit = executor.submit(() -> {
//远程调用了别的服务
return doctorSetAdminService.queryDoctorList(setId);
});
Future<List<DoctorListVO>> submit2 = executor.submit(() -> {
return doctorSetAdminService.queryDoctorList(setId);
});
//和上面 queryDoctorList 一样只是queryDoctorListAsy() 方法都是打了 `@Async` 注解
doctorSetAdminService.queryDoctorListAsy(setId);
doctorSetAdminService.queryDoctorListAsy(setId);
List<DoctorListVO> doctorListVOS = submit.get();
List<DoctorListVO> doctorListVOS2 = submit2.get();
return doctorListVOS;
}
从上面可以看出,SwCallableWapper
就是我插件的span
标识,并且多线程可以正常追踪
简单概括就是,代理了ThreadPoolExecutor
类的execute
和submit
方法,然后替换了入参Runnable
和Callable
成包装类
具体插件的实现细节可以看包com.chy.skywalking.apm.plugin.ttl.threading
因为 原生的apm-agent.jar
,在bytebuddy
修改ThreadPoolExecutor
字节码前就已经把ThreadPoolExecutor
加入到虚拟机(写入log
的时候会启动线程池),导致织入失败
所以需要使用我提供的apm-agent.jar
来让ThreadPoolExecutor
不要过早加载
具体细节可以看 org.apache.skywalking.apm.agent.SkyWalkingAgent