0
点赞
收藏
分享

微信扫一扫

IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了

雷亚荣 2022-07-13 阅读 41


我们习惯于在本地开发的时候​​debug​​,能快速定位与解决问题,那部署在服务器上是不是就没有办法了呢?只能通过查看日志来定位?

不是的,在远端的服务器上,我们一样可以​​debug​​。

2 IDEA的debug

我们先来看一下在​​IntelliJ IDEA​​​直接​​debug​​是怎样的。

先准备一个简单的​​Java​​程序:


package com.pkslow.basic;
import java.util.Map;

public class RemoteDebug {
public static void main(String[] args) {
System.out.println("------------------start------------------");

System.out.println("get all the system environment");
Map<String, String> envs = System.getenv();

System.out.println("\nprint out the contains `HOME`");
System.out.println("------env HOME------");
envs.entrySet().stream()
.filter(env -> env.getKey().contains("HOME"))
.forEach(env -> {
System.out.println(env.getKey() + ":" + env.getValue());
});

System.out.println("------------------end------------------");
}
}


功能很简单,获取所有系统环境变量,并打印出含有​​HOME​​字段的。

​Debug​​很简单,直接点击以下按钮就可以:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_定位


相信大家都知道这一点,但应该很多人都不会注意,​​IDEA​​究竟做了什么,为什么就可以调试了呢?我们看一下控制台的日志就明白了:


/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:59313,suspend=y,server=n -javaagent:/Users/pkslow/Library/Caches/IntelliJIdea2019.3/captureAgent/debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/charsets.jar:" com.pkslow.basic.RemoteDebug
Connected to the target VM, address: '127.0.0.1:59313', transport: 'socket'


简化一下,不重要的参数去掉:


java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:59313,suspend=y,server=n com.pkslow.basic.RemoteDebug


这就是可以​​Debug​​​的原因,利用了​​Java Agent​​​原理。这个功能很强大,类似一个​​AOP​​​,代理了​​Java​​程序,可以利用它进行调试、热部署等。

3 调试本地程序

我们先试试如何可以调试本地程序,不是直接在​​IDEA​​​上调试。先要编译出​​class​​​文件​​RemoteDebug.class​​​,然后按​​package​​​结构放好。我通过​​mvn clean compile​​来编译。

启动程序,在​​target/classes/​​目录执行:


$ java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:50050,suspend=y,server=y com.pkslow.basic.RemoteDebug
Listening for transport dt_socket at address: 50050


然后程序就会等待调试客户端的连接,不会往下执行。

配置​​IDEA​​以进行调试:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_java_02


配置完成保存后,点击​​debug​​就可以了:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_定位_03


程序已经进入​​debug​​模式:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_jdk_04


我们已经执行到了其中一行,现在看看服务端:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_linux_05


与​​IDEA​​​是同步的,并且确实已经控制了服务端​​Java​​的执行。

4 远程调试Linux Java程序

先把程序部署在​​Linux​​上:


$ scp -P 22 ./com/pkslow/basic/RemoteDebug.class root@xxx.xx.xx.xxx:/root/remoteDebug/com/pkslow/basic/
RemoteDebug.class 100% 2572 282.5KB/s 00:00


通过以下命令在服务端启动程序,这里调试端口改为​​9999​​,因为部分端口在远程服务器并没有开启:


java -agentlib:jdwp=transport=dt_socket,address=9999,suspend=y,server=y com.pkslow.basic.RemoteDebug


本地电脑​​IDEA​​配置如下:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_linux_06


开始​​debug​​​,正常控制了远程服务端的​​Java​​:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_linux_07


服务端的实时执行情况:



IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_jdk_08


让程序执行完如下:


$ java -agentlib:jdwp=transport=dt_socket,address=9999,suspend=y,server=y com.pkslow.basic.RemoteDebug
Listening for transport dt_socket at address: 9999
------------------start------------------
get all the system environment

print out the contains `HOME`
------env HOME------
JAVA_HOME:/root/jdk1.8.0_131
HOME:/root
------------------end------------------


5 总结

本文一步步探索如何进行调试远程的服务器,这在出现问题时定位还是非常有用的。毕竟可以实时看到服务端运行环境。

原作者:南瓜慢说


IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了_jdk_09


举报

相关推荐

0 条评论