eclipse中远程调试JVM(以启动namenode进程为例)

来源:互联网 发布:查找淘宝用户购买记录 编辑:程序博客网 时间:2024/05/19 14:39

通过远程调试JVM来跟踪Job在Hadoop集群环境中的执行过程,以达到源码跟踪的目的。在本文中以调试NameNode进程的启动过程为例,对NameNode的程序进行JVM远程调试。

在eclipse中进行远程调试的步骤
1.在客户端保留java的源代码。
2.在服务器端要有与源代码对应的类库
3.同时需要设置java虚拟机的动作,让其能够进行远程调试

启用NameNode程序的JVM远程调试

[远端(namenode)]
1.在Windows上查看java远程调试的帮助

c:/>java -agentlib:jdwp=help

2.设java虚拟机的远程调试

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 //设置java虚拟机的参数,启用远程调试

3.给namenode启动时增加jvm的远程调试功能的两种实现方式
a.修改bin/hdfs启动脚本

HADOOP_NAMENODE_OPTS=$HADOOP_NAMENODE_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000

这种做法带来的弊端是每回启动NameNode进程的时候,都会开启JVM远程调试的功能;若不想启用,需要每回修改bin目录下的hdfs脚本,这样会带来的许多不必要的麻烦
b.在shell当中直接设置环境变量

$>export HADOOP_NAMENODE_OPTS="$HADOOP_NAMENODE_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"

完成远程调试后,关闭远程调试功能

$>export HADOOP_NAMENODE_OPTS=

这种直接在终端中操作的方法,相比第一种方法要方便许多

4.启动名称节点

$>hadoop-daemon.sh start namenode

[客户端]
1.在eclipse中找到NameNode类,在main函数上打断点
2.eclipse右键调试 –> remote java application
具体设置如下所示:

项目:myhadoopConnectionType:standard(socket attach)host:s100port:8000

3.调试
启用调试

具体操作步骤

0.要先启动hadoop集群,再设置改变量,否则启动集群会一直等待
1.先杀死名称节点
在s100上操作:

$>hadoop-daemon.sh stop namenode

注:namenode是一个java的进程,它就应该是独立运行的java程序,具有main函数
考察org.apache.hadoop.hdfs.server.namenode.NameNode

2.查看java远程调试的帮助

$>java -agentlib:jdwp=help

显示结果如下:

Option Name and Value            Description                       Default---------------------            -----------                       -------suspend=y|n                      wait on startup?                  ytransport=<name>                 transport spec                    noneaddress=<listen/attach address>  transport spec                    ""server=y|n                       listen for debugger?              nlaunch=<command line>            run debugger on event             noneonthrow=<exception name>         debug on throw                    noneonuncaught=y|n                   debug on any uncaught?            ntimeout=<timeout value>          for listen/attach in milliseconds nmutf8=y|n                        output modified utf-8             nquiet=y|n                        control over terminal messages    n

3.设置java虚拟机的远程调试

$>java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000      //设置java虚拟机参数,启用远程调试功能

参数的解释:

transport   :   传输端口server      :   监听调试器(等待调试)suspend     :   等待启动address     :   监听端口

注意:只要设置这个之后,不管启动哪个java程序都会开启远程调试功能;当第一个远程调试开启之后,8000端口即被占用,之后的java程序将无法进行启动

4.(第一种方式)进行脚本分析(给namenode启动时,增加jvm的远程调试功能,使用对脚本修改的方式进行)

[sbin/hadoop-daemon.sh]// 如果启动的是namenode,就会调用bin/hdfs脚本hadoop_rotate_log $logecho starting $command, logging to $logcd "$HADOOP_PREFIX"case $command in  namenode|secondarynamenode|datanode|journalnode|dfs|dfsadmin|fsck|balancer|zkfc)    if [ -z "$HADOOP_HDFS_HOME" ]; then      hdfsScript="$HADOOP_PREFIX"/bin/hdfs    else      hdfsScript="$HADOOP_HDFS_HOME"/bin/hdfs    fi

[bin/hdfs]—->修改改脚本,开启远程调试功能

if [ "$COMMAND" = "namenode" ] ; then  CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'  #myself add options  HADOOP_NAMENODE_OPTS=$HADOOP_NAMENODE_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"

注意:这种方式是恒久化的,只要namenode一启动,就会停在这里,因此这种方式不可取

5.(第二种方式)在shell当值直接设置环境变量

$>export HADOOP_NAMENODE_OPTS="$HADOOP_NAMENODE_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"

6.在完成远程调试之后,就可以关闭远程调试功能(将该环境变量置空) 以防下次启动,又开启远程调试功能

$>export HADOOP_NAMENODE_OPTS=

7.echo环境变量

$>echo $HADOOP_NAMENODE_OPTS

8.启动名称节点

$>hadoop-daemon.sh start namenode

9.操作客户端(eclipse)
1.在org.apache.hadoop.hdfs.server.namenode.NameNode类中的main()函数处,随处打个断点,进行断点调试
2.eclipse右键调试 –> remote java application

项目:myhadoopConnectionTypestandard(socket attach)host:s100port:8000

调试前的效果如下:

这里写图片描述

调试成功,效果如下图所示:

启动namenode进程,有端口进行监听
这里写图片描述

namenode正在启动中
这里写图片描述

监听的端口
这里写图片描述
10.杀死NameNode的调试程序之后,NameNode进程随之也会跟着结束