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


    1 前言

    欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章!

    我们习惯于在本地开发的时候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("
    print 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很简单,直接点击以下按钮就可以:

    相信大家都知道这一点,但应该很多人都不会注意,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以进行调试:

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

    程序已经进入debug模式:

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

    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配置如下:

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

    服务端的实时执行情况:

    让程序执行完如下:

    $ 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 总结

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


    欢迎关注微信公众号<南瓜慢说>,将持续为你更新...

    多读书,多分享;多写作,多整理。

  • 相关阅读:
    常用linux命令
    console页面进去太慢优化
    CentOS7 查看最大线程连接数
    外部ssh连接Ubuntu系统
    Ubantu 防火墙管理
    oracle 闪回
    oracle用户密码过期
    base64编码原理
    Linux 备份数据库mysql
    python静态方法-类方法
  • 原文地址:https://www.cnblogs.com/larrydpk/p/13617060.html
Copyright © 2020-2023  润新知