JPDA 簡(jiǎn)介
Sun Microsystem 的 Java Platform Debugger Architecture (JPDA) 技術(shù)是一個(gè)多層架構(gòu),使您能夠在各種環(huán)境中輕松調(diào)試 Java 應(yīng)用程序。
JPDA 由兩個(gè)接口(分別是 JVM Tool Interface 和 JDI)、一個(gè)協(xié)議(Java Debug Wire Protocol)和兩個(gè)用于合并它們的軟件組件(后端和前端)組成。
它的設(shè)計(jì)目的是讓調(diào)試人員在任何環(huán)境中都可以進(jìn)行調(diào)試咸这。更詳細(xì)的介紹,您可以參考使用 Eclipse 遠(yuǎn)程調(diào)試 Java 應(yīng)用程序
JDWP 設(shè)置
JVM本身就支持遠(yuǎn)程調(diào)試,Eclipse也支持JDWP忆矛,只需要在各模塊的JVM啟動(dòng)時(shí)加載以下參數(shù):
dt_socket表示使用套接字傳輸。
address=8000 JVM在8000端口上監(jiān)聽(tīng)請(qǐng)求请垛,這個(gè)設(shè)定為一個(gè)不沖突的端口即可催训。
server=y y表示啟動(dòng)的JVM是被調(diào)試者洽议。如果為n,則表示啟動(dòng)的JVM是調(diào)試器漫拭。
suspend=y y表示啟動(dòng)的JVM會(huì)暫停等待亚兄,直到調(diào)試器連接上才繼續(xù)執(zhí)行。suspend=n嫂侍,則JVM不會(huì)暫停等待儿捧。
需要在$HADOOP_HOME/etc/hadoop/hadoop-env.sh文件的最后添加你想debug的進(jìn)程
遠(yuǎn)程調(diào)試namenode
export HADOOP_NAMENODE_OPTS="-agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=y"
遠(yuǎn)程調(diào)試datanode
export HADOOP_DATANODE_OPTS="-agentlib:jdwp=transport=dt_socket,address=9888,server=y,suspend=y"
遠(yuǎn)程調(diào)試RM(ResourceManager)
export YARN_RESOURCEMANAGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=10888,server=y,suspend=y"
遠(yuǎn)程調(diào)試NM(NodeManager)
export YARN_NODEMANAGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=10888,server=y,suspend=y"
簡(jiǎn)單介紹完遠(yuǎn)程debug協(xié)議JDWP之后我們開(kāi)始用實(shí)例來(lái)更好的理解它。我們調(diào)試看NameNode和DataNode是如何啟動(dòng)的挑宠,為了能夠進(jìn)行遠(yuǎn)程調(diào)試菲盾,我們需要給Hadoop的hadoop-env.sh文件進(jìn)行相應(yīng)的配置。如下圖所示各淀,我們把上面JDWP介紹的遠(yuǎn)程調(diào)試namenode和datanode的兩條配置粘到haoop-env.sh文件的最下方懒鉴,按ESC鍵退出編輯模式,然后先按Shift并且連續(xù)兩次按Z鍵碎浇,即可保存退出临谱。
我們先看看目前都有哪些進(jìn)程,我們使用命令jps來(lái)查看奴璃,發(fā)現(xiàn)目前只有兩個(gè)進(jìn)程悉默,一個(gè)是jps,另一個(gè)是eclipse苟穆。
接下來(lái)我們來(lái)啟動(dòng)namenode并且讓程序等待我們debug抄课,具體操作步驟如下所示,發(fā)現(xiàn)雳旅,我們?cè)谑褂妹?*./hadoop-daemon.sh start namenode開(kāi)啟namenode后程序會(huì)監(jiān)聽(tīng)8888端口跟磨,等待debug。nodenode也是一樣攒盈,只不過(guò)監(jiān)聽(tīng)的端口是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]#
這時(shí)可能我們會(huì)很好奇到底這時(shí)的進(jìn)程有哪些抵拘,那么我們就使用命令來(lái)看看,發(fā)現(xiàn)有4個(gè)進(jìn)程型豁,只不過(guò)兩個(gè)main都處于阻塞狀態(tài)僵蛛。
[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]#
接下來(lái)我們便開(kāi)始進(jìn)行debug了,為了更真實(shí)一點(diǎn)偷遗,我們?cè)赪indows系統(tǒng)上來(lái)進(jìn)行debug(服務(wù)器在Linux系統(tǒng)上)墩瞳,如果斷點(diǎn)能停在我們Windows系統(tǒng)上,那么就說(shuō)明我們真的實(shí)現(xiàn)了遠(yuǎn)程調(diào)試氏豌。
我們?cè)赗PC的例子上進(jìn)行驗(yàn)證喉酌,RPC這個(gè)小程序請(qǐng)參考:http://blog.csdn.net/u012453843/article/details/52496514這篇文章。我們按Ctrl+Shift+T快捷鍵,在打開(kāi)的對(duì)話(huà)框中輸入namenode泪电,發(fā)現(xiàn)果然有namenode這個(gè)類(lèi)般妙,如下圖所示
我們點(diǎn)擊上圖中標(biāo)紅的NameNode,進(jìn)入到NameNode類(lèi)當(dāng)中相速,當(dāng)然碟渺,默認(rèn)情況下我們是沒(méi)有關(guān)聯(lián)源碼的,因此要想查看源碼我們首先需要關(guān)聯(lián)一下源碼突诬,關(guān)于如何關(guān)聯(lián)源碼苫拍,大家可以參考:http://blog.csdn.net/u012453843/article/details/52590177這篇文章進(jìn)行關(guān)聯(lián)。關(guān)聯(lián)源碼后我們要找到它的main方法旺隙,我們用快捷鍵Ctrl+O绒极,在打開(kāi)的對(duì)話(huà)框中輸入main,如下圖所示蔬捷。
我們找到main方法后在開(kāi)始的地方打個(gè)斷點(diǎn)垄提,看一會(huì)兒程序會(huì)不會(huì)停到這個(gè)地方,如下圖所示:
接著我們右鍵周拐,在彈出的菜單中我們把鼠標(biāo)放到“Debug As”上铡俐,在它的子菜單中我們點(diǎn)擊“Debug Configurations...”,如下圖所示妥粟。
點(diǎn)擊上圖的“Debug Congigurations...”之后我們進(jìn)入到如下圖所示界面审丘,我們?cè)谧髠?cè)菜單中找到“Remote Java Appliaction”并雙擊它,就會(huì)出現(xiàn)下圖右側(cè)的內(nèi)容勾给,我們?cè)贑onnection Properties一欄的Host輸入我們Linux服務(wù)器的IP地址备恤,我的Linux服務(wù)器的IP地址是192.168.8.88,Port是我們前面遠(yuǎn)程Debug namenode配置的端口即8888锦秒,然后我們點(diǎn)擊"Apply",然后再點(diǎn)擊"Debug"喉镰,如下圖所示旅择。
接下來(lái)就是見(jiàn)證奇跡的時(shí)刻,我們發(fā)現(xiàn)程序確實(shí)進(jìn)入到我們打的斷點(diǎn)了B履贰生真!意味著我們遠(yuǎn)程調(diào)試成功了!我們從我們本地就可以調(diào)試遠(yuǎn)在服務(wù)器上的程序捺宗,這對(duì)我們程序員來(lái)說(shuō)是多么美好的事情啊柱蟀。在下面的代碼中有關(guān)于NameNode的創(chuàng)建過(guò)程,感興趣的同志們可以一步一步debug進(jìn)去一看究竟蚜厉。
我們直接讓上面的斷點(diǎn)走完长已,接著我們看datanode是否也可以遠(yuǎn)程debug成功,我們同樣在"Remote Java Application"上雙擊,這時(shí)會(huì)新創(chuàng)建一個(gè)配置類(lèi)DataNode.class
术瓮,Host依然是192.168.8.88康聂,端口要改為9888,因?yàn)榕渲玫臅r(shí)候就是9888胞四,接下來(lái)點(diǎn)擊"Apply"和"Debug"恬汁,如下圖所示
我們發(fā)現(xiàn)程序果然進(jìn)入main所設(shè)置的斷點(diǎn)了,如下圖所示辜伟。
這樣NameNode和DataNode都以debug的模式啟動(dòng)了氓侧,我們還可以以debug的方式進(jìn)行多種調(diào)試。