远程调试(remote debug)示例

在开发过程中,总是会遇到本地无法重现服务器端报错的问题,这时候远程调试(remote debug)就是很好的应对方法。

下面我们来看一下怎么使用jvm的远程调试能力。

前提

本地需要有源码,有源码才可以敲断点调试。

编写启动脚本

在实际项目中我们往往是通过脚本来启动Java程序,我们需要在启动命令上添加参数来开启远程debug模式。

需要添加的命令如下

-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=y

以下是一份常见的启动脚本示例

#!/bin/bash

# get current folder.
CMD_DIR=$(cd $(dirname $0); pwd)
cd "$CMD_DIR/.."
CURRENT_DIR=$(pwd)
echo User dir: "$CURRENT_DIR"
CONF_DIR="$CURRENT_DIR/conf"
STATIC_DIR="$CURRENT_DIR/static"
ARGS=$*

# get file name.
FILE_PATH="$CURRENT_DIR/lib"
files=$(ls "$FILE_PATH")
for filename in $files
do
   echo Main Jar: $filename
done
if [[  -f "$CONF_DIR/application.yml" || -f "$CONF_DIR/bootstrap.yml" ]]; then
    echo "Startup app $filename with parameter: $ARGS "
    nohup java \
    -server \
    -Dspring.web.resources.static-locations="$STATIC_DIR/" \
    -Dspring.config.location="$CONF_DIR/" \
    -Dkoca.config.location="config" \
    -Dkoca.lcp.dump.location="$CURRENT_DIR/" \
    -Dlogging.config="$CONF_DIR/logback-spring.xml" \
    -Dspring.banner.location="file:$CONF_DIR/banner.txt" \
    -Duser.timezone=GMT+08 \
    -Xdebug \
    -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=y \
    -jar "$CURRENT_DIR/lib/$filename" \
    $ARGS \
    >./nohup.log 2>&1 &
else
    echo "Configuration folder or files is not exist."
fi

运行启动脚本

我们修改脚本后,将这份脚本上传到服务器。

正常启动时,程序会有一大堆运行日志。但是使用这份脚本启动后,程序启动时会卡住,等待其他客户端连接debug端口。

这个debug端口就是命令中设置的5005。

本地创建客户端

本地使用IDEA创建客户端。

修改host为服务器地址

创建完毕后运行该客户端,运行时该客户端会和服务端建立连接。

可以看到原本卡住的服务端开始正常运行。

在本地的代码中敲断点,就可以进行debug了,和平时在本地debug没什么差别。