JPDA 简介
Sun Microsystem 的 Java Platform Debugger Architecture (JPDA) 技术是一个多层架构,使您能够在各种环境中轻松调试 Java 应用程序。
JPDA 由两个接口(分别是 JVM Tool Interface 和 JDI)、一个协议(Java Debug Wire Protocol)和两个用于合并它们的软件组件(后端和前端)组成。
它的设计目的是让调试人员在任何环境中都可以进行调试。更详细的介绍,您可以参考使用 Eclipse 远程调试 Java 应用程序
JDWP 设置
JVM本身就支持远程调试,Eclipse也支持JDWP,只需要在各模块的JVM启动时加载以下参数:
dt_socket表示使用套接字传输。
address=8000 JVM在8000端口上监听请求,这个设定为一个不冲突的端口即可。
server=y y表示启动的JVM是被调试者。如果为n,则表示启动的JVM是调试器。
suspend=y y表示启动的JVM会暂停等待,直到调试器连接上才继续执行。suspend=n,则JVM不会暂停等待。
需要在$HADOOP_HOME/etc/hadoop/hadoop-env.sh文件的最后添加你想debug的进程
远程调试namenode
export HADOOP_NAMENODE_OPTS="-agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=y"
远程调试datanode
export HADOOP_DATANODE_OPTS="-agentlib:jdwp=transport=dt_socket,address=9888,server=y,suspend=y"
远程调试RM(ResourceManager)
export YARN_RESOURCEMANAGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=10888,server=y,suspend=y"
远程调试NM(NodeManager)
export YARN_NODEMANAGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=10888,server=y,suspend=y"
简单介绍完远程debug协议JDWP之后我们开始用实例来更好的理解它。我们调试看NameNode和DataNode是如何启动的,为了能够进行远程调试,我们需要给Hadoop的hadoop-env.sh文件进行相应的配置。如下图所示,我们把上面JDWP介绍的远程调试namenode和datanode的两条配置粘到haoop-env.sh文件的最下方,按ESC键退出编辑模式,然后先按Shift并且连续两次按Z键,即可保存退出。
我们先看看目前都有哪些进程,我们使用命令jps来查看,发现目前只有两个进程,一个是jps,另一个是eclipse。
接下来我们来启动namenode并且让程序等待我们debug,具体操作步骤如下所示,发现,我们在使用命令**./hadoop-daemon.sh start namenode开启namenode后程序会监听8888端口,等待debug。nodenode也是一样,只不过监听的端口是9888**
[root@itcast01 hadoop]# cd /itcast/hadoop-2.2.0/sbin
[root@itcast01 sbin]# ls
distribute-exclude.sh httpfs.sh start-all.sh start-yarn.cmd stop-dfs.cmd yarn-daemon.sh
hadoop-daemon.sh mr-jobhistory-daemon.sh start-balancer.sh start-yarn.sh stop-dfs.sh yarn-daemons.sh
hadoop-daemons.sh refresh-namenodes.sh start-dfs.cmd stop-all.cmd stop-secure-dns.sh
hdfs-config.cmd slaves.sh start-dfs.sh stop-all.sh stop-yarn.cmd
hdfs-config.sh start-all.cmd start-secure-dns.sh stop-balancer.sh stop-yarn.sh
[root@itcast01 sbin]#** ./hadoop-daemon.sh start namenode
starting namenode, logging to /itcast/hadoop-2.2.0/logs/hadoop-root-namenode-itcast01.out
Listening for transport dt_socket at address: 8888**
[root@itcast01 sbin]# ./hadoop-daemon.sh start datanode
starting datanode, logging to /itcast/hadoop-2.2.0/logs/hadoop-root-datanode-itcast01.out
Listening for transport dt_socket at address: 9888
[root@itcast01 sbin]#
这时可能我们会很好奇到底这时的进程有哪些,那么我们就使用命令来看看,发现有4个进程,只不过两个main都处于阻塞状态。
[root@itcast01 sbin]# jps
3711 -- main class information unavailable
3761 -- main class information unavailable
3088 org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
3802 Jps
[root@itcast01 sbin]#
接下来我们便开始进行debug了,为了更真实一点,我们在Windows系统上来进行debug(服务器在Linux系统上),如果断点能停在我们Windows系统上,那么就说明我们真的实现了远程调试。
我们在RPC的例子上进行验证,RPC这个小程序请参考:http://blog.csdn.net/u012453843/article/details/52496514这篇文章。我们按Ctrl+Shift+T快捷键,在打开的对话框中输入namenode,发现果然有namenode这个类,如下图所示
我们点击上图中标红的NameNode,进入到NameNode类当中,当然,默认情况下我们是没有关联源码的,因此要想查看源码我们首先需要关联一下源码,关于如何关联源码,大家可以参考:http://blog.csdn.net/u012453843/article/details/52590177这篇文章进行关联。关联源码后我们要找到它的main方法,我们用快捷键Ctrl+O,在打开的对话框中输入main,如下图所示。
我们找到main方法后在开始的地方打个断点,看一会儿程序会不会停到这个地方,如下图所示:
接着我们右键,在弹出的菜单中我们把鼠标放到“Debug As”上,在它的子菜单中我们点击“Debug Configurations...”,如下图所示。
点击上图的“Debug Congigurations...”之后我们进入到如下图所示界面,我们在左侧菜单中找到“Remote Java Appliaction”并双击它,就会出现下图右侧的内容,我们在Connection Properties一栏的Host输入我们Linux服务器的IP地址,我的Linux服务器的IP地址是192.168.8.88,Port是我们前面远程Debug namenode配置的端口即8888,然后我们点击"Apply",然后再点击"Debug",如下图所示。
接下来就是见证奇迹的时刻,我们发现程序确实进入到我们打的断点了!!意味着我们远程调试成功了!我们从我们本地就可以调试远在服务器上的程序,这对我们程序员来说是多么美好的事情啊。在下面的代码中有关于NameNode的创建过程,感兴趣的同志们可以一步一步debug进去一看究竟。
我们直接让上面的断点走完,接着我们看datanode是否也可以远程debug成功,我们同样在"Remote Java Application"上双击,这时会新创建一个配置类DataNode.class
,Host依然是192.168.8.88,端口要改为9888,因为配置的时候就是9888,接下来点击"Apply"和"Debug",如下图所示
我们发现程序果然进入main所设置的断点了,如下图所示。
这样NameNode和DataNode都以debug的模式启动了,我们还可以以debug的方式进行多种调试。