基于JavaAgent的全链路监控五《ThreadLocal链路追踪》

阅读: 评论:0

基于JavaAgent的全链路监控五《ThreadLocal链路追踪》

基于JavaAgent的全链路监控五《ThreadLocal链路追踪》

章节列表 | 关注微信公众号,bugstack虫洞栈,回复<基于JavaAgent的全链路监控>获取源码

  • 基于JavaAgent的全链路监控一《嗨!JavaAgent》
  • 基于JavaAgent的全链路监控二《通过字节码增加监控执行耗时》
  • 基于JavaAgent的全链路监控三《ByteBuddy操作监控方法字节码》
  • 基于JavaAgent的全链路监控四《JVM内存与GC信息》
  • 基于JavaAgent的全链路监控五《ThreadLocal链路追踪》
  • 基于JavaAgent的全链路监控六《开发应用级监控》

案例简述

Google开源的Dapper链路追踪组件,并在2010年发表了论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,这篇文章是业内实现链路追踪的标杆和理论基础,具有非常大的参考价值。目前,链路追踪组件有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鹰眼)等,它们都是非常优秀的链路追踪开源组件。本文主要讲述如何在Spring Cloud Sleuth中集成Zipkin。在Spring Cloud Sleuth中集成Zipkin非常的简单,只需要引入相应的依赖和做相关的配置即可。


当业务程序代码在线上运行时,实例A、实例B、实例C,他们直接可能从上到下依次调用,为了能很好的监控程序的调用链路,我们需要对调用链路进行追踪监控。实例的外部可能是通过RPC、HTTP、SOCKET、WEBSERVICE等方式进行调用,内部是方法逻辑依次执行。外部例如http可以通过在头部写入追踪ID进行监控,内部使用threadlocal进行保存上下文关系。{ThreadLocal变量特殊的地方在于:对变量值的任何操作实际都是对这个变量在线程中的一份copy进行操作,不会影响另外一个线程中同一个ThreadLocal变量的值。}

环境准备
1、IntelliJ IDEA Community Edition
2、jdk1.8.0_45 64位

配置信息(路径相关修改为自己的)
1、配置位置:Run/Debug Configurations -> VM options
2、配置内容:-javaagent:E:itstackGITitstackitstack-demo-agentitstack-demo-agent-05targetitstack-demo-agent-05-1.0.0-SNAPSHOT.jar=testargs

代码示例

itstack-demo-agent-05
├── l
└── src├── main│   ├── java│   │   └── org.itstack.demo.agent│   │       ├──	track│   │ 	    │   ├── TrackContext.java	│   │ 	    │   └── TrackManager.java	│   │       ├── MyAdvice.java│   │	    └── MyAgent.java│	└── resources│       └── META-INF│           └── MANIFEST.MF 	└── test└── java└── org.st└── ApiTest.java

TrackContext.java

/*** 博客:* 论坛:* 公众号:bugstack虫洞栈  {获取学习源码}* create by fuzhengwei on 2019*/
public class TrackContext {private static final ThreadLocal<String> trackLocal = new ThreadLocal<String>();public static void clear(){ve();}public static String getLinkId(){();}public static void setLinkId(String linkId){trackLocal.set(linkId);}}

TrackManager.java

/*** 追踪管控* 博客:* 论坛:* 公众号:bugstack虫洞栈  {获取学习源码}* create by fuzhengwei on 2019*/
public class TrackManager {private static final ThreadLocal<Stack<String>> track = new ThreadLocal<Stack<String>>();private static String createSpan() {Stack<String> stack = ();if (stack == null) {stack = new Stack<>();track.set(stack);}String linkId;if (stack.isEmpty()) {linkId = LinkId();if (linkId == null) {linkId = "nvl";TrackContext.setLinkId(linkId);}} else {linkId = stack.peek();TrackContext.setLinkId(linkId);}return linkId;}public static String createEntrySpan() {String span = createSpan();Stack<String> stack = ();stack.push(span);return span;}public static String getExitSpan() {Stack<String> stack = ();if (stack == null || stack.isEmpty()) {TrackContext.clear();return null;}return stack.pop();}public static String getCurrentSpan() {Stack<String> stack = ();if (stack == null || stack.isEmpty()) {return null;}return stack.peek();}}

MyAdvice.java

/*** 博客:* 论坛:* 公众号:bugstack虫洞栈  {获取学习源码}* create by fuzhengwei on 2019*/
public class MyAdvice {@Advice.OnMethodEnter()public static void enter(@Advice.Origin("#t") String className, @Advice.Origin("#m") String methodName) {String linkId = CurrentSpan();if (null == linkId) {linkId = UUID.randomUUID().toString();TrackContext.setLinkId(linkId);}String entrySpan = ateEntrySpan();System.out.println("链路追踪:" + entrySpan + " " + className + "." + methodName);}@Advice.OnMethodExit()public static void exit(@Advice.Origin("#t") String className, @Advice.Origin("#m") String methodName) {ExitSpan();}}

MyAgent.java

/*** javaagent* 博客:* 论坛:* 公众号:bugstack虫洞栈  {获取学习源码}* create by fuzhengwei on 2019*/
public class MyAgent {//JVM 首先尝试在代理类上调用以下方法public static void premain(String agentArgs, Instrumentation inst) {System.out.println("基于javaagent链路追踪");AgentBuilder agentBuilder = new AgentBuilder.Default();AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {builder = builder.(MyAdvice.class).on(ElementMatchers.isMethod().and(ElementMatchers.any()).(ElementMatchers.nameStartsWith("main")))));return builder;};agentBuilder = pe(ElementMatchers.nameStartsWith("org.st")).transform(transformer).asDecorator();//监听AgentBuilder.Listener listener = new AgentBuilder.Listener() {@Overridepublic void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {}@Overridepublic void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {System.out.println("onTransformation:" + typeDescription);}@Overridepublic void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {}@Overridepublic void onError(String s, ClassLoader classLoader, JavaModule javaModule, boolean b, Throwable throwable) {}@Overridepublic void onComplete(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {}};agentBuilder.with(listener).installOn(inst);}//如果代理类没有实现上面的方法,那么 JVM 将尝试调用该方法public static void premain(String agentArgs) {}}

MANIFEST.MF

Manifest-Version: 1.0
Premain-Class: org.itstack.demo.agent.MyAgent
Can-Redefine-Classes: true

ApiTest.java

/*** 线程内方法追踪* 博客:* 论坛:* 公众号:bugstack虫洞栈  {获取学习源码}* create by fuzhengwei on 2019* VM options:* -javaagent:E:itstackGITitstackitstack-demo-agentitstack-demo-agent-05targetitstack-demo-agent-05-1.0.0-SNAPSHOT.jar=testargs*/
public class ApiTest {public static void main(String[] args) {//线程一new Thread(() -> new ApiTest().http_lt1()).start();//线程二new Thread(() -> {new ApiTest().http_lt1();}).start();}public void http_lt1() {System.out.println("测试结果:hi1");http_lt2();}public void http_lt2() {System.out.println("测试结果:hi2");http_lt3();}public void http_lt3() {System.out.println("测试结果:hi3");}}

测试结果

基于javaagent链路追踪
onTransformation:class org.st.ApiTest
链路追踪:7dfd98e8-c474-461c-87b9-1da3bf6072c2 org.st.ApiTest.http_lt1
测试结果:hi1
链路追踪:7dfd98e8-c474-461c-87b9-1da3bf6072c2 org.st.ApiTest.http_lt2
测试结果:hi2
链路追踪:7dfd98e8-c474-461c-87b9-1da3bf6072c2 org.st.ApiTest.http_lt3
测试结果:hi3
链路追踪:69cdf9d3-1f42-4cf6-8d80-5362dd7ea140 org.st.ApiTest.http_lt1
测试结果:hi1
链路追踪:69cdf9d3-1f42-4cf6-8d80-5362dd7ea140 org.st.ApiTest.http_lt2
测试结果:hi2
链路追踪:69cdf9d3-1f42-4cf6-8d80-5362dd7ea140 org.st.ApiTest.http_lt3
测试结果:hi3Process finished with exit code 0

关注{bugstack虫洞栈}公众号获取源码

本文发布于:2024-02-05 06:24:21,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170726194363821.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:链路   JavaAgent   ThreadLocal
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23