一、问题概述
连接远程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吧,应该可以了
以上。