一、問題概述
連接遠程java應用除了jstatd方式,還有jmx方式。不必拘泥於一種,一種不行可以果斷嘗試另一種,興許就行了。
姊妹篇在這:
jvisualvm連接遠程應用終於成功,附踩大坑記錄!!(二:jmx方式)
目前,在jvisualvm連接失敗的相關互聯網博客中,我還沒看到有人和我一樣的解決方法。
兩天前,我像大家一樣,在網絡上搜索jvisualvm連接remote 應用的方法,然而,不知道為啥,我的開發機器的visualvm真就連不上遠程主機上的應用。
試了同事電腦,試了改端口,試了wireshark抓包,(主要是看連接建立了沒,我這邊的現象是:地址應該沒問題,不是網上很多博客說的hostname的問題,在本機向遠程機器上的jstatd
發起連接請求后,沒一會就被服務器端發了fin信號過來,把連接斷開了;看下圖,可以發現,有相當多的fin標志的消息)
總之,我試了不少辦法。后來才覺得可能本機的visualvm工具有問題(或者我本機環境有問題),后來我又試了同事電腦,也不行;后來沒法,只好試試開發用的服務器了(有一台windows server 2016的),結果,就成了。具體看下文吧。
jvisualvm連接遠程應用主要有兩種方式,一種是jstatd方式,這種的話,不需要應用預先設置jmx之類的參數,個人認為比較適合:遠程服務器上的需要分析的java程序已經很慢,不響應了,連不上了,這時候就可以啟動一個jstatd應用,供client主機連接;
一種是需要java應用啟動前,就設置jmx相關的參數,當應用變慢時,就可以用jvisualvm連上去,分析原因。
二、操作步驟之jstatd方式
1、創建文件jstatd.all.policy
我是在jdk目錄下的bin創建的,不在這應該也沒關系。
[root@pas bin]# pwd /usr/local/jdk1.8.0_161/bin
內容如下:(和網絡上的很多博客不一樣,我這邊指定了絕對路徑,沒采用java.home,主要是我踩坑的時候,方便排除路徑方面的影響)
grant codebase "file:/usr/local/jdk1.8.0_161/lib/tools.jar" { permission java.security.AllPermission; };
2、啟動jstatd后台應用
命令如下:
jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.19.114 -J-Djava.rmi.server.logCalls=true
(我是在/usr/local/jdk1.8.0_161/bin路徑下運行的下面的命令,該路徑下就有jstatd.all.policy文件。如果是在其他地方執行,記得指定絕對或相對路徑)
其中,
-J-Djava.security.policy=jstatd.all.policy 指定路徑
-J-Djava.rmi.server.logCalls=true 打印日志
-J-Djava.rmi.server.hostname=192.168.19.114 指定主機名,主機名應該和你用hostname -i命令執行出來的結果一致。
然后,我的/etc/hosts文件的內容如下:
[root@pas bin]# less /etc/hosts 192.168.19.114 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
不過,網絡上都說改了/etc/hosts中的127.0.0.1為自己的ip地址后,執行hostname -i的結果,就會是自己在/etc/hosts中設置的ip地址,然而,我的不是這樣:
其中的紅圈是我的ip地址:
ps:如需要修改端口(默認為1099):
jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.19.114 -J-Djava.rmi.server.logCalls=true -J-Djava.net.preferIPv4Stack=true -p 5555
其中:
-p 5555 ----------修改端口為5555
3、啟動后效果
[root@pas bin]# jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.19.114 -J-Djava.rmi.server.logCalls=true Jun 27, 2018 4:20:03 PM sun.rmi.server.UnicastServerRef logCall FINER: RMI TCP Connection(1)-192.168.19.114: [192.168.19.114: sun.rmi.registry.RegistryImpl[0:0:0, 0]: void rebind(java.lang.String, java.rmi.Remote)] Jun 27, 2018 4:20:03 PM sun.rmi.server.UnicastServerRef logCall FINER: RMI TCP Connection(2)-192.168.19.114: [192.168.19.114: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
4、客戶端連接-本機連接
注意到了嗎,連接后,沒有半點反應。
和網絡上那些順風順水的寶寶們比起來,是不是很心累。。。我的為啥不行。不要急。我們換台電腦。
4、客戶端連接-其他主機進行連接
在我翻遍了互聯網上上百個網頁后,幾乎要放棄的時候,我決定再試試。
換了台電腦,一台開發用的服務器,系統是windows server 2016,裝的jdk版本是jdk-8u121-windows-x64
三、結論
遇到bug時,可以嘗試換台電腦吧。。。不過,你也不用瞎換。
經過我的嘗試,我找到了一個穩定的組合,保證可以連上。
1、安裝win7虛擬機
我在我的vmvare里,安裝了一台虛擬機(win7 64位),鏡像用的是下面這個(復制到迅雷下載):
ed2k://|file|cn_windows_7_ultimate_x64_dvd_x15-66043.iso|3341268992|7DD7FA757CE6D2DB78B6901F81A6907A|/
原始網站在這:
2、安裝java
我用的是下面這個版本:
jdk-8u121-windows-x64.exe
3、試試visualvm吧,應該可以了
以上。