- 浏览: 2147803 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
(一)Btrace的介绍
BTrace是Java的安全可靠的动态跟踪工具。 他的工作原理是通过 instrument + asm 来对正在运行的java程序中的class类进行动态增强,可以在不用重启的情况下监控系统运行情况,方便的获取程序运行时的数据信息,如方法参数、返回值、全局变量和堆栈信息等,并且做到最少的侵入,占用最少的系统资源。
正如上面描述的一些特性,所以btrace一般是用来排查生产环境jvm问题的一款利器,使用它不用再担心应用程序的日志打的不够全,不够细,也不用为了排查问题一遍遍的重启程序。
(二)Btrace的一些限制
由于Btrace会把脚本逻辑直接侵入到运行的代码中,所以在使用上做很多限制:
1、不能创建对象
2、不能使用数组
3、不能抛出或捕获异常
4、不能使用循环
5、不能使用synchronized关键字
6、属性和方法必须使用static修饰
此外不恰当的使用BTrace可能导致生产程序直接挂掉,所以在上生产环境之前,务必在开发环境充分验证脚本的正确性。
(三)Btrace能干什么
(1)分析任意接口或者方法的耗时情况
(2)分析不断的添加数据时,Map的扩容情况
(3)分析那个方法里面调用了System.gc()方法,并打印出其调用栈
(4)某些方法抛出异常时,分析其运行参数
(5)统计一些接口的调用次数
(6)分析一些方法的代码是否执行到了某一行
(7)..........
注意上面的所有操作,都是监控正在运行中的程序,基本不会产生任何影响。
(四)Btrace的安装
(1)从github上下载最新的二进制包 ,版本是1.3.10.2
wget https://github.com/btraceio/btrace/releases/download/v1.3.10.2/btrace-bin-1.3.10.2.tgz
(2)解压到指定路径
(3)设置环境变量
```` BTRACE_HOME=/root/btrace export BTRACE_HOME export PATH=$PATH:$BTRACE_HOME/bin ````
(4)验证安装是否成功
```` [root@es1 ~]# btrace --version BTrace v.1.3.10 (20171121) ````
(5)查看btrace的帮助文档
```` [root@es1 build]# btrace Usage: btrace <options> <pid> <btrace source or .class file> <btrace arguments> where possible options include: --version Show the version -v Run in verbose mode -o <file> The path to store the probe output (will disable showing the output in console) -u Run in trusted mode -d <path> Dump the instrumented classes to the specified path -pd <path> The search path for the probe XML descriptors -classpath <path> Specify where to find user class files and annotation processors -cp <path> Specify where to find user class files and annotation processors -I <path> Specify where to find include files -p <port> Specify port to which the btrace agent listens for clients -statsd <host[:port]> Specify the statsd server, if any ````
(五)Btrace使用的一个例子
注意btrace在maven上发布的jar,版本非常低,都是几年前的版本了,如果要编写btrace脚本,建议把安装目录下三个核心jar直接拷贝到工程中临时使用即可,如果想要随时使用,也可以将其上传到你们公司的maven私服上。
```` [root@es1 btrace]# ll build/ 总用量 1572 -rw-r--r--. 1 root root 460271 12月 16 00:44 btrace-agent.jar -rw-r--r--. 1 root root 358679 12月 16 00:44 btrace-boot.jar -rw-r--r--. 1 root root 785219 12月 16 00:44 btrace-client.jar ````
(1)在使用btrace之前,我们先需要写一个简单的java程序,模拟成是线上正在跑的程序
代码比较简单,就是每隔随机的时间,随机生成两个整数,进行求和:
```` package com.test; import java.util.Random; public class BtraceTest { public static Random random=new Random(); public int add (int a, int b) { int sum=a+b; System.out.println("和:"+sum); return a+b; } public void run(){ try { while (true) { add(random.nextInt(10), random.nextInt(10)); Thread.sleep(random.nextInt(10) * 100); } }catch (Exception e){ e.printStackTrace(); } } public static void main(String[] args) { new BtraceTest().run(); } } ````
(2)主程序已经有了,下面就需要我们写btrace脚本,来监控"我们的线上程序了"
注意,需要在工程里面引入上面提到的3个jar。
监控的代码如下:
```` package samples; import com.sun.btrace.BTraceUtils; import com.sun.btrace.annotations.*; import com.sun.btrace.annotations.Export; import static com.sun.btrace.BTraceUtils.*; @BTrace public class OnlineDebug { @OnExit//当成程序退出时,执行一些命令 public static void onexit(int code) { println("BTrace program exits! with code: " + code); } @Export //可以用来统计调用次数 public static long counter; @OnMethod(clazz="com.test.BtraceTest", method="add", location=@Location(value=Kind.RETURN)) public static void m(@Self Object self, int a,int b,@Return int result,@Duration long time) { BTraceUtils.println("参数: a: "+a+" b: "+b); BTraceUtils.println("花费时间: "+time*1.0/1000+"ms"); jstack();//打印堆栈信息 counter++; } @OnEvent("1")//通过事件触发,打印当前的程序调用次数 public static void setL1() { BTraceUtils.println("executor count: "+counter); } //监控程序是否走到第22行代码 @OnMethod(clazz = "com.test.BtraceTest", location = @Location(value = Kind.LINE, line = 22)) public static void onBind() { println("执行到第22行"); } //每隔指定时间打印一下调用次数 @OnTimer(5000) public static void run(){ BTraceUtils.println("executor count: "+counter); } // //慎用 监控程序里面是否调用了,java.lang下面的一些类或方法 // @OnMethod(clazz="/java\\.lang\\..*/", method="/.*/") // public static void swingMethods( @ProbeClassName String probeClass, @ProbeMethodName String probeMethod) { // print("entered " + probeClass + "." + probeMethod); // } } ````
(六)模拟测试
经过步骤五,我们已经准备好了模拟程序和监控脚本,下面来部署测试下:
(1)首先,通过maven将模拟程序打包成一个jar
(2)选择一台linux机器将jar包上传
(3)执行命令,启动模拟程序
```` java -cp xxx.jar com.test.BtraceTest ````
linux终端输出内容如下:
```` 和:8 和:11 和:3 和:12 和:14 和:15 和:8 和:2 和:8 和:7 和:18 和:4 ````
(4)打开另一个linux终端部署监控脚本OnlineDebug.java到指定目录
赋予执行权限:
```` chmod +x OnlineDebug.java ````执行jps命令,查看模拟程序的进程id
启动监控脚本:
```` btrace 2139 OnlineDebug.java ````
等待几秒后,控制台输出如下:
```` 参数: a: 0 b: 8 花费时间: 101.973ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) 参数: a: 3 b: 4 花费时间: 116.611ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) 参数: a: 0 b: 2 花费时间: 113.168ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) 参数: a: 7 b: 7 花费时间: 113.434ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) 参数: a: 6 b: 1 花费时间: 181.184ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) 参数: a: 7 b: 6 花费时间: 190.881ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) executor count: 44 ````
可以看到监控脚本已经生效,成功获取到了模拟程序的内部参数,以及执行时间等。此刻另一个终端的模拟程序还在
正常运行,但内部其实已经被增强了。
如何退出监控脚本?
非常简单,执行ctrl+c命令,选择1退出即可:
```` 参数: a: 9 b: 9 花费时间: 246.743ms com.test.BtraceTest.add(BtraceTest.java:11) com.test.BtraceTest.run(BtraceTest.java:17) com.test.BtraceTest.main(BtraceTest.java:28) 参数: a: 3 b: 1 花费时间: 251.039ms ^CPlease enter your option: 1. exit 2. send an event 3. send a named event 4. flush console output 1 ````
总结:
通过上面的例子,相信大家可以感受到btrace的强大,用其来排查正在运行的程序问题非常方便,感兴趣的朋友们可以自己试一试。
参考链接:
https://github.com/btraceio/btrace/wiki/BTrace-Annotations
https://yq.aliyun.com/articles/7569
https://www.jianshu.com/p/93e94b724476
有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。
发表评论
-
记一次log4j不打印日志的踩坑记
2019-09-22 01:58 1462### 起因 前几天一个跑有java应用的生产集群(200多 ... -
在Java里面如何解决进退两难的jar包冲突问题?
2019-07-23 19:10 1144如上图所示: es api组件依赖guava18.0 ... -
如何轻松理解二叉树的深度遍历策略
2019-07-03 23:33 1021我们知道普通的线性数据结构如链表,数组等,遍历方式单一 ... -
为什么单线程Redis性能也很出色
2019-01-21 18:02 2135高性能的服务器,不一 ... -
如何将编程语言里面的字符串转成数字?
2019-01-11 23:23 1996将字符串转成数字在很 ... -
为什么Java里面String类是不可变的
2019-01-06 18:36 1590在Java里面String类型是不可变对象,这一点毫无疑问,那 ... -
关于Java里面volatile关键字的重排序
2019-01-04 18:49 986Java里面volatile关键字主 ... -
多个线程如何轮流打印ABC特定的次数?
2018-12-11 20:42 5932之前的一篇文章,我给 ... -
聊聊Java里面的引用传递
2018-11-16 21:21 938长久以来,在Java语言里面一直有一个争论,就是Java语言到 ... -
理解计数排序算法的原理和实现
2018-10-11 10:03 2048计数排序(Counting sort) ... -
理解Java7和8里面HashMap+ConcurrentHashMap的扩容策略
2018-09-06 11:31 3343### 前言 理解HashMap和Con ... -
关于Java里面多线程同步的一些知识
2018-07-18 09:45 1065# 关于Java里面多线程同步的一些知识 对于任何Java开 ... -
Java单例模式之双检锁深入思考
2018-07-08 12:25 3245# Java单例模式之双检锁 ... -
关于Java里面多线程同步的一些知识
2018-07-08 12:23 1084# 关于Java里面多线程同步的一些知识 对于任何Java开 ... -
重新认识同步与异步,阻塞和非阻塞的概念
2018-07-06 14:30 1428# 重新认识同步与异步 ... -
线程的基本知识总结
2018-06-27 16:27 1021### (一)创建线程的方式 (1)实现Runnable接口 ... -
Java里面volatile关键字修饰引用变量的陷阱
2018-06-25 11:42 1329# Java里面volatile关键字修饰引用变量的陷阱 如 ... -
关于Java里面的字符串拼接,你了解多少?
2018-06-25 11:28 1318# 关于Java里面的字符串 ... -
深入理解Java内存模型的语义
2018-06-25 11:39 693### 前言 Java内存模型( ... -
如何证明Java多线程中的成员变量数据是互不可见的
2018-06-21 10:09 1456前面的几篇文章主要介绍了Java的内存模型,进程和线程的定义, ...
相关推荐
介绍Greys介绍3. 实例-使具排查问题urs新提供了远程cookie的校验jar包,其中关键的法为远程调法CookieDecoder.requestDeco
Java诊断利器Arthas排查问题实践.pptx
Java常见问题排查
《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关的知识与技巧。《Java程序性能优化:让你的Java程序更快、更稳定》共6章,先后从软件设计、软件编码、JVM调优...
JAVA线上问题排查和工具 内容详细 结合实际工作 贴合实际
java程序性能优化Java是目前应用最为广泛的软件开发平台,学习针对Java程序的优化方法有重要的现实意义。《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关的...
Java虚拟机调优及问题排查手册:包括JVM排查、数据库连接排查、堆栈快照排查。Java虚拟机调优及问题排查手册:包括JVM排查、数据库连接排查、堆栈快照排查。
Java问题定位技术的文档,可以用于快速的排查和定位使用java程序开发的应用程序系统。
排查java程序 cpu爆满
Java线上故障排查方案(2).pdf
java程序性能优化与排查,分析代码性能问题,解决效率问题。
Java是目前应用最为广泛的软件开发平台,学习针对Java程序的优化方法有重要的现实意义。《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关的知识与技巧。 ...
Java常见问题排查,基于JVM进行深度问题排查、JVM调优
《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关的知识与技巧。 《Java程序性能优化:让你的Java程序更快、更稳定》共6章,先后从软件设计、软件编码、JVM...
生产中Java性能问题排查:请求响应过程、DNS查找过程、请求响应过程
Java服务器问题排查思路及工具集.zip linux工具集 java工具集 cpu占用率高如何解决 内存占用率高如何解决 OOM(out of memory)如何解决