问题描述
线上接口慢,查询 skywalking trace ,尝试定位响应时间慢的环节,却发现大部分时间都在 self duration 上,百思不得其解。最终,对比之前的 skywalking trace,发现 trace 链路中少了 okhttp client 的调用环节。
问题解决
经检查发现,中间件团队升级某个 sdk 使用了 4.x 版本的 okhttp。在 maven 项目的依赖树中存在多个相同依赖的不同版本时,就会出现版本覆盖问题。Maven 默认会选择其中的一个版本进行构建,可能会导致依赖冲突或不一致的情况。这就导致了我们项目里面所有 okhttp 的版本都被替换成了 4.x 版本。
在平台团队提供的基础镜像中,打包的是 apm-okhttp-3.x-plugin-8.1.0.jar,该 plugin 只能适配 okhttp 3.x,无法为 4.x 版本的 okhttp client 生成代理对象,也就无法实现 trace 功能。解决问题:使用 exclusions 标签排除 sdk 中的 okhttp 依赖。
skywalking agent 原理:启动 java 应用时带上参数 -javaagent:/opt/tools/skywalking-agent.jar。SkyWalking Agent 会使用字节码注入技术,将特定的代码插入到应用程序的字节码中。这样,Agent 就能够捕获关键的方法调用、请求处理和其他操作的信息。
一般来说,skywalking 会为要追踪的类生成代理对象,这样就能捕获关键方法的性能指标和跟踪数据。开启 agent.is_open_debugging_class 配置,SkyWalking agent 会将生成的 instrumented classes 文件保存在 /debugging 目录。
在异步模式下,数据收集和传输是在 Agent 自己的线程或线程池中进行的,应用程序的业务线程可以继续运行而不需要等待数据传输的完成(推荐)。通过 jstack 看到的线程:grpc-nio-worker-ELG-1-1 ~ grpc-nio-worker-ELG-1-15,就是 skywalking agent 所使用的线程池,默认会使用 16 个线程。修改 transport.grpc.upstream.thread-count 配置更改 gRPC 线程组数量, 修改 transport.grpc.upstream.max-concurrent-calls 配置可以调整 gRPC 最大并发调用数。