java线上排查神器:btrace使用示例
问题背景
最近我的一个正在生产环境运行的程序出现了故障,问题简单描述一下就是:这个程序需要实现任务调度,程序设置有最大运行数量的限制,如果一个任务失败了,那么这个任务在之后就会被重新调度,但是实际情况是这个失败了的任务并没有被重新调度,而是卡死了。
在阅读代码之后,发现需要打印程序中一个map类型的类属性的内容来定位最终的问题所在。但是,这种bug只发生在负载较大的时候,所以非常难复现。如果把程序停止,然后修改代码,运行新的程序,再想要复现这个bug就很困难了。
在查阅资料后,我发现了btrace这个工具可以完美解决我的需求。
BTrace简介
这个工具的官方Github仓库链接为:https://github.com/btraceio/btrace
官方对于这个工具的描述如下:
BTrace is a safe, dynamic tracing tool for the Java platform.
BTrace can be used to dynamically trace a running Java program (similar to DTrace for OpenSolaris applications and OS). BTrace dynamically instruments the classes of the target application to inject tracing code ("bytecode tracing").
简单而言,这个工具可以把一段代码动态的插入到一个正在运行的Java程序里,而无需停止这个程序。其思想有点类似于动态插桩。关于BTrace的具体原理后面我会写一篇文章来解析一下。
但是,插入的代码是会受到一定的限制的,其中对本次编程影响最大的就是:方法调用只能有对BTraceUtils里面的方法的调用,如果有对其他方法的调用,就会报如下所示的错误:

使用BTrace
BTrace的具体使用这里就不赘述了,网上有很多博客介绍了这个工具的基本使用方法。(需要注意的是,网上很多文章代码里面引用的包已经过时了,如果遇到引用包错误的问题,建议看看btrace给的samples里面的代码,可以在这个里面的代码的基础上做自己的开发)
以下主要介绍一下怎样编写BTrace脚本来打印程序中的类属性。主要的思想是使用反射机制,BTrace脚本被注入之后,就和程序在同一个进程空间里了,那么就可以通过反射机制来获取到目标类的Class,然后获取到Field,最后通过对象来获取到这个类属性的值。具体的实现代码如下:
import org.openjdk.btrace.core.annotations.BTrace;
import org.openjdk.btrace.core.annotations.Injected;
import org.openjdk.btrace.core.annotations.OnMethod;
import org.openjdk.btrace.core.annotations.ProbeClassName;
import org.openjdk.btrace.core.annotations.ProbeMethodName;
import org.openjdk.btrace.core.annotations.Self;
import org.openjdk.btrace.core.annotations.ServiceType;
import org.openjdk.btrace.services.impl.Printer;
import org.openjdk.btrace.core.BTraceUtils;
import java.lang.reflect.Field;
import java.util.Map;
/**
* This script traces method entry into every method of
* every class in javax.swing package! Think before using
* this script -- this will slow down your app significantly!!
*/
@BTrace
public class WatchMapTrace {
@OnMethod(
clazz = "com.server.download.SubTaskDistributeCenter",
method = "autoDistribute"
)
public static void m(@Self Object o, @ProbeClassName String probeClass, @ProbeMethodName String probeMethod) {
Class c=BTraceUtils.classForName("com.qzero.server.download.SubTaskDistributeCenter",BTraceUtils.contextClassLoader());
Field f=BTraceUtils.field(c,"threadMap",true);
Map map=(Map)BTraceUtils.get(f,o);
BTraceUtils.print(map+"");
// Get the element of map
Thread thread=(Thread)BTraceUtils.get(map,109579);
BTraceUtils.print("Thread status : "+BTraceUtils.threadState(thread));
}
}
代码是基于samples里面的AllMethods.java改的,其中的OnMethod注解指定了需要被插桩的方法,Self注解可以获取到含有这个方法的对象。
这里比较麻烦的点就是,btrace不允许除BTraceUtils以外的方法调用,不过好在BTraceUtils里面也给出了很多常用的方法,例如反射相关的,还有操作Map相关的,具体可以查看BTraceUtils.java的源码,链接如下:https://github.com/btraceio/btrace/blob/develop/btrace-core/src/main/java/org/openjdk/btrace/core/BTraceUtils.java
把这段脚本使用BTrace加载到正在运行的程序上,等到autoDistribute再次被调用时,程序里就会打印threadMap里面的内容了,我也是由此定位到了问题所在。
java线上排查神器:btrace使用示例的更多相关文章
- Java线上问题排查神器Arthas快速上手与原理浅谈
前言 当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题: 程序在稳定运行了,可是实现的功能点了没反应. 为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题? 想到可 ...
- Java线上问题排查思路及Linux常用问题分析命令学习
前言 之前线上有过一两次OOM的问题,但是每次定位问题都有点手足无措的感觉,刚好利用星期天,以测试环境为模版来学习一下Linux常用的几个排查问题的命令. 也可以帮助自己在以后的工作中快速的排查线上问 ...
- Arthas - Java 线上问题定位处理的终极利器
前言 在使用 Arthas 之前,当遇到 Java 线上问题时,如 CPU 飙升.负载突高.内存溢出等问题,你需要查命令,查网络,然后 jps.jstack.jmap.jhat.jstat.hprof ...
- linux实用指令 | 程序员线上排查必知必会linux指令(持续更新中)
Linux线上排查程序员实用指南 一.乱码问题 二.帮助指令 1. help命令 2. man命令 3. info命令 三.性能监测与优化 1. top命令 参考资源 Linux线上排查程序员实用指南 ...
- 【转】java线上程序排错经验2 - 线程堆栈分析
前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...
- 线上排查:内存异常使用导致full gc频繁
线上排查:内存异常使用导致full gc频繁 问题系统 日常巡检发现,应用线上出现频繁full gc 现象 应用线上出现频繁full gc 排查过程 分析dump 拉dump文件:小插曲:dump时如 ...
- BTrace : Java 线上问题排查神器
BTrace 是什么 BTrace 是检查和解决线上的问题的杀器,BTrace 可以通过编写脚本的方式,获取程序执行过程中的一切信息,并且,注意了,不用重启服务,是的,不用重启服务.写好脚本,直接用命 ...
- Java线上问题排查神器Arthas实战分析
概述 背景 是不是在实际开发工作当中经常碰到自己写的代码在开发.测试环境行云流水稳得一笔,可一到线上就经常不是缺这个就是少那个反正就是一顿报错抽风似的,线上调试代码又很麻烦,让人头疼得抓狂:而且deb ...
- JAVA线上常见问题排查手段(小结)
在平时开发过程中,对于线上问题的排查以及系统的优化,免不了和Linux进行打交道.每逢大促和双十一,对系统的各种压测性能测试,优化都是非常大的一次考验.抽空整理了一下自己在线上问题排查以及系统优化的一 ...
- Java线上应用故障排查之二:高内存占用
搞Java开发的,经常会碰到下面两种异常: 1.java.lang.OutOfMemoryError: PermGen space 2.java.lang.OutOfMemoryError: Java ...
随机推荐
- AI 制作游戏美术素材流程分享(程序员方向粗糙版)
AI 制作游戏美术素材分享(程序员方向粗糙版) 视频讲解: 抖音:https://www.douyin.com/user/self?from_tab_name=main&modal_id=75 ...
- Java11 ThreadLocal的remove()方法源码分析
1. ThreadLocal实现原理 本文参考的java 版本是11. 在讲述ThreadLocal实现原理之前,我先来简单地介绍一下什么是ThreadLocal.ThreadLocal提供线程本地变 ...
- 【2020.11.25提高组模拟】树的解构(deconstruct) 题解
[2020.11.25提高组模拟]树的解构(deconstruct) 题解 题目描述 给一棵以\(1\)为根的外向树,进行\((n-1)\)次删边操作,每次都会从没有删掉的边中等概率地删掉一条边\(a ...
- springboot的代理模式示例----面向切面编程
1.定义切面类 2.编写切面类 import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMappe ...
- OceanBase 中的身外身法 —— Auto DOP(自适应并行)使用技巧分享
首先为大家推荐这个 OceanBase 开源负责人老纪的公众号 "老纪的技术唠嗑局",会持续更新和 OceanBase 相关的各种技术内容.欢迎感兴趣的朋友们关注! Part 1 ...
- ESP32-Arduino物联网工控(二)串口转TCP转发机:WIFI连接,手机连WIFI配置热点名字
先上代码,欢迎伸手党. #include <WiFi.h> #include <ESPmDNS.h> #include <WebServer.h> #include ...
- Opencv学习:使用Opencv对图象进行抠图和滤镜处理,实现“你的名字”动漫图片效果
最近接到了一个坑爹题目,是这么要求的: 仿照 <你的名字>,对天坛图像.src.jpg进行处理.要求 (一)背景(天空)分割,替换后再融合 在自然界的图片中,很难出现动漫中大多大多的云彩. ...
- Just:告别 Makefile 的现代命令行任务运行器
本文推荐的一个轻量级命令行工具--Just,它提供了一种简单高效的方式来管理项目任务,类似于传统的 Make 工具,但具有更简洁的语法和更现代化的功能. 我目前在一些小项目中开始使用它来管理一些日常的 ...
- 数据湖选型指南|Hudi vs Iceberg 数据更新能力深度对比
数据湖作为新一代大数据基础设施,近年来持续火热,许多前线的同学都在讨论数据湖应该怎么建,许多企业也都在构建或者计划构建自己的数据湖.基于此,自然引发了许多关于数据湖选型的讨论和探究.但是经过搜索之后我 ...
- HyperWorks使用六面体和三棱柱单元进行实体网格剖分
本节将演示如何使用 solid map 功能对一个复杂的几何实体进行网格剖分.剖分的思路是:首先对该实体进行适当的切割,以使其各个部分均处于 mappable 的状态:然后分别对各个子块进行 soli ...