【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
transmittable-thread-local以下简称:TTL
根据InheritableThreadLocal在线程池中上下文传递的问题可以知道这个threadLocal的值传递,在父子线程之间若使用了线程池的技术,会导致子线程的threadLocal信息错乱。
根据分布式追踪系统场景下,如何使用TTL 知道ttl的实现原理,通过线程池的封装,threadLocal的继承实现了traceId的传递,采用weakHashMap取代引用计数的方法实现了GC的回收防止内存泄漏。
以下具体问题具体分析,给出的是以agent方式代码无侵入接入
TTL描述了四种场景
分布式跟踪系统
日志收集记录系统上下文
Session级Cache
应用容器或上层框架跨应用代码给下层SDK传递信息
分布式跟踪系统
snowball-common里的traceId是不是TTL推荐的分布式追踪系统场景下,如何使用TTL ,根据issue的描述,文章讲的是分布式追踪相关的设计和ttl在其中的应用,而在snowball-common的问题里,是关于slf4j的MDC问题,若继续探究请进入:APM 模块
日志收集记录系统
根据InheritableThreadLocal在线程池中上下文传递的问题,知道InheritableThreadLocal这个类完成了上下文传递,但是由于池的存在,当线程被下一次重复使用的时候,由于Map的内容没有更新,出现了traceId的重复(也就是不对应)
Session级Cache、应用容器给下层SDK传递信息
这两个不属于本次所讨论内容。。。
TTL在日志收集系统的两种实现
log4j2-ttl-thread-context-map
pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>log4j2-ttl-thread-context-map</artifactId>
<version>1.3.0</version>
<scope>runtime</scope>
</dependency>
只需将此依赖项添加到您的项目中即可激活Log4j2 TTL ThreadContextMap
通过log4j2.threadContextMap=com.alibaba.ttl.log4j2.TtlThreadContextMap的方式将MDC的adapter实现进行替换
logback-mdc-ttl
pom.xml
<dependency>
<groupId>com.ofpay</groupId>
<artifactId>logback-mdc-ttl</artifactId>
<version>1.0.2</version>
</dependency>
在Java的启动参数加上:
-Xbootclasspath/a:/path/to/transmittable-thread-local-2.x.x.jar
-javaagent:/path/to/transmittable-thread-local-2.x.x.jar
在logback配置文件中增加TtlMdcListener
<?xml version="1.0" encoding="UTF-8"?>
<configuration >
<!-- ...(略) -->
<contextListener class="com.ofpay.logback.TtlMdcListener"/>
<!--例子: %X{uuid} 支持在跨线程池时传递-->
<property scope="context" name="APP_PATTERN"
value='%d{yyyy-MM-dd HH:mm:ss.SSS}|%X{uuid}|%level|%M|%C\:%L|%thread|%replace(%.-2000msg){"(\r|\n)","\t"}|"%.-2000ex{full}"%n'/>
</configuration>
通过将contextListener的方式,将MDC的adapter实现进行替换
TTL在snowball-common中的应用
snowball-common在webFilter中将应用接收的请求,采用Twitter的finagle框架自带的TraceID放入到MDC中,而且整个采用了slf4j的日志框架
因此,就基于logback-mdc-ttl的方案对snowball-common进行升级
pom.xml引入
<dependency>
<groupId>com.ofpay</groupId>
<artifactId>logback-mdc-ttl</artifactId>
<version>1.0.2</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.11.0</version>
</dependency>
至此,升级工作完毕
应用升级snowball-common
pom.xml
在snowball-common的version版本>-5.0.3
<dependency>
<groupId>com.xueqiu.snowball</groupId>
<artifactId>snowball-common</artifactId>
<!-- version 大于等于5.0.3 -->
<version>5.0.3</version>
</dependency>
pom引入agent的依赖包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.11.0</version>
</dependency>
start_server.sh
在启动脚本上添加JVM参数,将agent的路径换成自己的
-javaagent:../lib/transmittable-thread-local-2.11.0.jar
-Xbootclasspath/a:../lib/transmittable-thread-local/2.11.0/transmittable-thread-local-2.11.0.jar
logback.xml
在logback的配置问价中添加contextListener参数
<contextListener class="com.ofpay.logback.TtlMdcListener"/>
以上升级工作完毕
性能评估:
https://github.com/alibaba/transmittable-thread-local/blob/master/docs/performance-test.md
参考资料:
https://github.com/oldratlee/log4j2-ttl-thread-context-map
https://github.com/ofpay/logback-mdc-ttl
https://github.com/alibaba/transmittable-thread-local
https://www.infoq.cn/article/javaagent-illustrated
http://lovestblog.cn/blog/2014/06/18/jvm-attach/
————————————————
来源:oschina
链接:https://my.oschina.net/xiaominmin/blog/3150648