对于常见的 WEB 容器,Takin 通过增强 org.apache.catalina.core.StandardHostValve#invoke 方法,拦截并解析方法入参的 Request 对象中的 header 数据,判断压测标的信息并将压测标以及链路信息设置到上下文对象,并通过 ThreadLocal 保存该上下文对象,以此来保证当前线程处理的过程中都能获取到压测标以及链路信息。

但是不管是 WEB 容器还是业务代码经常会使用线程池运行代码,这时候 ThreadLocal 就有局限性了,如何做到跨线程池传递我们的上下文对象就显得异常重要了,好在 Alibaba 的https://github.com/alibaba/transmittable-thread-local解决了这个问题,具体 transmittable-thread-local 的详细内容大家可以通过 git 地址查看,这里我们主要以 git 上的 demo 看看 transmittable-thread-local 如何实现跨线程传递的,主要通过将线程池运行的 Runnable 对象包装成 TtlRunnable 对象并保存当前的上下文信息。这样就完成了对线程池运行任务的压测标以及链路数据信息的透传,至此似乎一切都很完美。

直到某次出现了一个诡异的现象,在使用 Takin 的过程中,有一应用接入 Takin 之后,某个功能无法正常使用,但是无论是应用的日志还是 Takin 的日志都未显示任何异常信息,再追问了无法使用的功能是一个线程池执行任务,当时扩展了 ThreadPoolExecutor 的 beforeExecute 方法和 afterExecute 方法,用以记录任务执行的耗时,并且会打印任务的 taskId 等信息,通过截图的 Debug 信息便可以看到问题出现了,由于使用了 transmittable-thread-local 导致原始的 Runnable 被包装成了 TtlRunnable 对象,在这个过程中如果业务想要再获取 Runnable 对象强转获取一些任务信息,就会出现类无法转换的异常。

解决方案的话目前可以通过增强 beforeExecute 和 afterExecute 方法,对 Runnable 对象进行判断,如果是 TtlRunnable 对象,则通过 TtlRunnable.getRunnable()方法返回原是的 Runnable 对象

Takin 开源详情https://news.shulie.io/?p=3024

立即扫码,入群技术交流~

【Takin使用日记】记一次TransmittableThreadLocal引起的业务异常的更多相关文章

  1. 【记】研究Sharding-JDBC遇到的一个异常(Caused by: io.shardingsphere.core.exception.ShardingException: Cannot get uniformed table structure for `t`. The different meta data of actual tables are as follows)

    一.异常信息 Caused by: io.shardingsphere.core.exception.ShardingException: Cannot get uniformed table str ...

  2. 记一次monolog的RotatingFileHandler使用

    需求如下: 1.需要一种日记格式,能把同一次请求的日记归在一起,请求间的日记以空行隔开,即使并发操作也不会像laravel默认的日记一样很"被动"的记录(不同请求的日记可能被交替记 ...

  3. Unity 序列化 总结

    查找了 Script Serialization http://docs.unity3d.com/Manual/script-Serialization.html 自定义序列化及例子: http:// ...

  4. 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?

    写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...

  5. [翻译]AKKA笔记 -ACTOR SUPERVISION - 8

    失败更像是分布式系统的一个特性.因此Akka用一个容忍失败的模型,在你的业务逻辑与失败处理逻辑(supervision逻辑)中间你能有一个清晰的边界.只需要一点点工作,这很赞.这就是我们要讨论的主题. ...

  6. 项目编码规范(Ali)

    一.研发流程规范 二.SQL编码规范 数据库命名规范:数据库名一律小写,必须以字母开头.库名包含多个单词的,以下划线“_”分隔.如果采用分库方案,分库编号从“0”开始,用“0”左补齐为四位. 表名规范 ...

  7. Java 之 异常处理

    1.异常: a.问题(Throwable):异常(Exception).错误(Error)   异常(Exception):运行时异常(RuntimeException).编译时异常(Unhandle ...

  8. Reed-Solomon码,QR

    原文: Reed–Solomon codes for coders参考: AN2407.pdfWIKI: 里德-所罗门码实现:Pypi ReedSolo #译注:最近看到了RS码,发现还挺有意思的,找 ...

  9. 让我们一起写出更有效的CSharp代码吧,少年们!

    周末空闲,选读了一下一本很不错的C#语言使用的书,特此记载下便于对项目代码进行重构和优化时查看. Standing On Shoulders of Giants,附上思维导图,其中标记的颜色越深表示在 ...

随机推荐

  1. 第05课:GDB 常用命令详解(上)

    本课的核心内容如下: run 命令 continue 命令 break 命令 backtrace 与 frame 命令 info break.enable.disable 和 delete 命令 li ...

  2. React Native踩坑日记 —— tailwind-rn

    项目背景 在项目的初始阶段,我们需要建立自己的design system,我们spike了一些方案,tailwind-rn就是其中一种,如果有用到或者即将用到tailwind-rn的,可以进来看一看, ...

  3. golang 注释 exported function xxx should have comment or be unexported

    0x00 问题 exported function xxx should have comment or be unexported. 0x01 解决 https://golang.org/s/sty ...

  4. javascript/html 禁止图片缓存

    更新图片, 如果图片的url没有改变, 刷新页面之后图片会使用缓存的图片 Solutions: * js改变图片链接 (添加get参数) // 假设当前这个图片的dom对象为img img.src + ...

  5. LR虚拟用户已设置集合点,但controller无法设置集合点策略的解决方案

    原文来自:https://blog.csdn.net/qq_34982914/article/details/90905030 学习loadrunner的过程中,肯定涉及集合点的添加,但是我们按照书上 ...

  6. CF444C-DZY Loves Colors【线段树,set】

    正题 题目链接:https://www.luogu.com.cn/problem/CF444C 题目大意 \(n\)个物品第\(i\)个颜色为\(i\),权值为\(0\).要求支持\(m\)次操作 给 ...

  7. 《HelloGitHub》第 66 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这里有实战项目.入门教程.黑科技.开源书籍.大厂开源项目等,涵盖多种编程语言 Pyt ...

  8. Redis 高可用篇:你管这叫主从架构数据同步原理?

    在<Redis 核心篇:唯快不破的秘密>中,「码哥」揭秘了 Redis 五大数据类型底层的数据结构.IO 模型.线程模型.渐进式 rehash 掌握了 Redis 快的本质原因. 接着,在 ...

  9. MySQL学习总结:提问式回顾 undo log 相关知识

    原文链接:MySQL学习总结:提问式回顾 undo log 相关知识 1.redo 日志支持恢复重做,那么如果是回滚事务中的操作呢,也会有什么日志支持么? 也回滚已有操作,那么就是想撤销,对应的有撤销 ...

  10. Vue组件间的数据传输

    1.父组件向子组件传输数据:自定义属性 1 //父组件 2 <Son :msg="message" :user="userinfo"></So ...