这个Bug的排查之路,真的太有趣了。 (下)

简介: 这个Bug的排查之路,真的太有趣了。 (下)

继续挖掘


问题解决了,但是问题背后的问题,还没有得到解决:

Monitor Ctrl-Break 线程是啥?它是怎么来的?

我们先 jstack 一把看看线程堆栈呗。

而在 idea 里面,这里的“照相机”图标,就是 jstack 一样的功能。


image.png

我把程序恢复为最初的样子,然后把“照相机”就这么轻轻的一点:

image.png

从线程堆栈里面可以看到 Monitor Ctrl-Break 线程来自于这个地方:

com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

而这个地方,一看名称,是 idea 的源码了啊?

不属于我们的项目里面了,这咋个搞呢?

思考了一下,想到了一种可能,于是我决定用 jps 命令验证一下:

看到执行结果的时候我笑了,一切就说的通了。

果然,是用了 -javaagent 啊。

那么 javaagent 是什么?

好的,要问答好这个问题,就得另起一篇文章了,本文不讨论,先欠着。

只是简单的提一下。

你在命令行执行 java 命令,会输出一大串东西,其中就包含这个:

image.png

什么语言代理的,看不懂。

叫我们参阅 java.lang.instrument。

那它又是拿来干啥的?

简单的一句话解释就是:

使用 instrument 可以更加方便的使用字节码增强的技术,可以认为是一种 jvm 层面的截面。不需要对程序源代码进行任何侵入,就可以对其进行增强或者修改。总之,有点 AOP 内味。

-javaagent 命令后面需要紧跟一个 jar 包。

-javaagent:<jar 路径>[=<选项>]

instrument 机制要求,这个 jar 包必须有 MANIFEST.MF 文件,而 MANIFEST.MF 文件里面必须有 Premain-Class 这个东西。

所以,回到我们的程序中,看一下 javaagent 后面跟的包是什么。

在哪看呢?

就这个地方:

image.png

你把它点开,命令非常的长。但是我们关心的 -javaagent 就在最开始的地方:

image.png

image.png

image.png

image.png


此时此刻,我们距离真相,只有一步之遥了。

进到对应的包里,发现有三个 class 类:

image.png

image.png

image.png

我说过什么来着?

来,大声的跟我念一遍:源码之下无秘密。

Monitor Ctrl-Break 线程就是这里来的。

而仔细看一眼这里的代码,这个线程在干啥事呢?

Socket client = new Socket("127.0.0.1", portNumber);

啊,我的天呐,来看看这个可爱的小东西,socket 编程,太熟悉了,简直是梦回大学实验课的时候。

它是链接到 127.0.0.1 的某个端口上,然后 while(true) 死循环等待接收命令。

那么这个端口是哪个端口呢?

就是这里的 62325:

image.png

需要注意的是,这个端口并不是固定的,每次启动这个端口都会变化。


玩玩它


既然它是 Socket 编程,那么我就玩玩它呗。

先搞个程序:

public class SocketTest{
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(12345);
        System.out.println("等待客户端连接.");
        Socket socket = serverSocket.accept();
        System.out.println("有客户端连接上了 "+ socket.getInetAddress() + ":" + socket.getPort() +"");
        OutputStream outputStream = socket.getOutputStream();
        Scanner scanner = new Scanner(System.in);
        while (true)
        {
            System.out.println("请输入指令: ");
            String s = scanner.nextLine();
            String message = s + "\n";
            outputStream.write(message.getBytes("US-ASCII"));
        }
    }
}

我们把服务端的端口指定为了 12345。

客户端这边的端口也得指定为 12345,那怎么指定呢?

别想复杂了,简单的一比。

把这行日志粘贴出来:

image.png需要说明的是,我这边为了演示效果,在程序里面加了一个 for 循环。

然后我们在这里把端口改为 12345:


image.png

把文件保存为 start.bat 文件,随便放一个地方。

万事俱备。

我们先把服务端运行起来:

image.png

在 cmd 窗口里面输出了我们的日志,说明程序正常运行。

而在服务端这边,显示有客户端连接成功。

叫我们输入指令。

输入啥指令呢?

看一下客户端支持哪些指令呗:

image.png

可以看到,支持 STOP 命令。

接受到该命令后,会退出程序。

来,搞一波,动图走起:

image.png

搞定。

好了,本文技术部分就到这里了,恭喜你知道了 idea 中的 Monitor Ctrl-Break 线程,这个学了没啥卵用的知识 。

如果要深挖的话,往 -javaagent 方向挖一挖。

应用很多的,比如耳熟能详的 Java 诊断工具 Arthas 就是基于 JavaAgent 做的。

有点意思。


最后说一句


才疏学浅,难免会有纰漏,如果你发现了错误的地方,可以在后台提出来,我对其加以修改。

感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。

目录
相关文章
|
Dubbo Java 应用服务中间件
项目中引进这玩意,排查日志又快又准
随着微服务盛行,很多公司都把系统按照业务边界拆成了很多微服务,在排错查日志的时候,因为业务链路贯穿着很多微服务节点,导致定位某个请求的日志以及上下游业务的日志会变得有些困难。
|
5月前
|
SQL 关系型数据库 MySQL
(十八)MySQL排查篇:该如何定位并解决线上突发的Bug与疑难杂症?
前面《MySQL优化篇》、《SQL优化篇》两章中,聊到了关于数据库性能优化的话题,而本文则再来聊一聊关于MySQL线上排查方面的话题。线上排查、性能优化等内容是面试过程中的“常客”,而对于线上遇到的“疑难杂症”,需要通过理性的思维去分析问题、排查问题、定位问题,最后再着手解决问题,同时,如果解决掉所遇到的问题或瓶颈后,也可以在能力范围之内尝试最优解以及适当考虑拓展性。
278 3
|
7月前
|
XML SQL 前端开发
Bug积累
Bug积累
51 1
|
8月前
|
网络协议 容灾 NoSQL
阿里云DTS踩坑经验分享系列|网络问题排查大法
在DTS的所有用户问题中,网络问题出现的概率居高不下,很大程度上是由于DTS的链路复杂性,从源数据库到DTS再从DTS到目的数据库,任意的一个部位发生网络不通、网络质量问题都有可能导致DTS任务的中断,或者延迟。本文希望以一种最简单的模型,简述DTS网络不通问题的排查方法,并给出一些简单的验证思路及手段,排查方向对了才能事半功倍。
109151 3
阿里云DTS踩坑经验分享系列|网络问题排查大法
|
运维 监控 前端开发
记一次线上 bug 的排查分析过程及总结
记一次线上 bug 的排查分析过程及总结
记一次线上 bug 的排查分析过程及总结
|
Java API 容器
java项目排查bug
java项目排查bug
138 0
|
Arthas NoSQL Java
线上服务器CPU100%的真相排查【Bug利器Arthas】
这起CPU100%的事故,由某个客户演示的bug暴露出来,气氛比较尴尬....
772 0
线上服务器CPU100%的真相排查【Bug利器Arthas】
|
消息中间件 监控 算法
JVM技术之旅-线上分析排查问题
JVM技术之旅-线上分析排查问题
307 0
JVM技术之旅-线上分析排查问题
|
测试技术
如何处理不能复现的bug?软件测试工程师避坑指南
软件测试工作中常常会遇到不能复现的bug,遇到这种情况其实很正常,但是很多测试新手都按照自己的想法处理,没有提交bug,或者匆匆关闭bug。线上出现问题,就只能自己背锅了。
573 0
|
Web App开发 移动开发 前端开发
技术分享 | Bug定位方法
技术分享 | Bug定位方法