JMX:无法从 Windows 盒子连接来监视 Linux 系统上的 JMX 端口
我在 JDK1.6 中对 jconsole.exe 和 JVisualVM.exe 有丰富的经验,并且已经通过 JMX.remote 从 Windows JVM 连接到另一台计算机上的 Windows JVM 数千次,但当我尝试监视时失败在 Linux 主机上运行的 java 实例(从 Windows 主机,我在 Amazon EC2 的 Redhat 和 SUSE 上尝试了 JMX 侦听器)。我也尝试使用 jconsole.exe 并得到类似的错误。
有没有人能想到这种 JMX 连接会出现问题的原因。我可以尝试什么想法吗?有没有人“实际上”做到了这一点并且可以说如果我坚持下去就会有效?
我从 JVisualVM 得到的错误(在远程连接尝试中)是这样的:
"Cannot connect using service:jmx:rmi:///jndi/rmi://<jmx service ip>:8001/jmxrmi"
我的远程 JMX 服务配置是这样的:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8001
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.hostname=<jmx service ip>
在 此链接,但它没有回答我的问题。
我验证了“iptables”没有作为服务启用并且没有打开,所以我不认为存在任何类型的防火墙阻塞。此外,Windows 和 Linux 计算机都位于 10.0.0.0 私有内部子网中。我能够 telnet 到端口 8001 来验证它的存在以及它在 Linux 机器上的监听 (netstat -ap)。
I have a lot of experience with jconsole.exe and JVisualVM.exe , in the JDK1.6 and have connected thousands of times from a Windows JVM over to a Windows JVM on another machine via JMX.remote but it fails when I try to monitor a java instance that is running on a Linux host (from a Windows host and I tried JMX listener on redhat and SUSE at Amazon EC2). I also tried using jconsole.exe and get a similar error.
Is there any reason anyone can think of , why this kind of JMX connection would have a problem. Any ideas I can try? Has anyone "actually" done this and can say it will work if I persevere?
The error I get from JVisualVM (on the remote connect attempt) is something like this:
"Cannot connect using service:jmx:rmi:///jndi/rmi://<jmx service ip>:8001/jmxrmi"
My remote JMX service config is like this:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8001
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.hostname=<jmx service ip>
Found a similar question at this link but it didn't answer my question.
I verified that "iptables" is not enabled as a service and is not on and so I don't imaging there is any sort of firewall blockage. Also, both the windows and linux machine are on a 10.0.0.0 private internal subnet together. I am able to telnet into the port 8001 to verify its there , and its listening (netstat -ap) on the linux machine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请参阅系统属性 java.rmi.server.hostname< /a>.在 Linux 服务器 JVM 上,将此系统属性设置为主机的公共 IP。然后在客户端 JMX URL 中使用公共 IP。
See the system property java.rmi.server.hostname. On your Linux server JVM, set this system property to be the public IP of the host. Then use the public IP in you client JMX URL.
我认为您的问题是 RMI 实现很难穿过防火墙,例如它需要的端口数量超过您指定的端口才能工作。如果您连接到自己的计算机或同一网络上的计算机,您通常不会注意到这些事情。
这篇文章很好地描述了您将遇到的问题
如果我是你,我会尝试将 jmxmp 设置为替代协议。为此,您需要添加 jmxremote_optional.jar(从 Oracle 免费下载,下载 “JMX 远程 API 1.0.1_04 参考实现”从此处)到服务器和 jvisualvm 类路径,但这是值得的。
如果您在 google 上搜索 jmxmp,您会发现很多有关如何设置的示例,我的第一个命中是 http://pub.admc.com/howtos/jmx/distributed-chapt.html#jmxmp-sect 这可能有点太面向代码了,但我在这里添加它不管怎样,因为它用几句好句子解释了像大多数 jmxmp 一样的事情。
如何定义服务器端端点取决于您正在运行的内容。大多数应用程序服务器将允许您输入启用 jmxmp 的 jmx 服务 url,但如果服务器是从头开始编写的,您可能必须在代码中自行设置它,而不是使用您习惯的 java 的 -D 开关。
尝试一下,如果遇到问题,请返回并提出更具体的问题。
编辑:
将 jar 添加到类路径后,您在代码中唯一需要做的事情(假设您没有使用已经为您处理它的服务器应用程序)如下(省略声明、异常处理等无论如何弄清楚):
I think your problem is that the RMI implementation is kind of hard to work with through firewalls and such as it requires more than the port you specify to work. Things you typically wouldn't notice if you connect to your own machine or a machine on the same network.
This post describes the problems you will run into quite well
If I were you, I would try to setup jmxmp as an alternative protocol. To do so you need to add the jmxremote_optional.jar (free from Oracle, download "JMX Remote API 1.0.1_04 Reference Implementation" from here) to both the server and the jvisualvm classpath but it is worth it.
If you google for jmxmp you will find quite a few examples on how to set things up, one of my first hits are http://pub.admc.com/howtos/jmx/distributed-chapt.html#jmxmp-sect which may be a bit too code oriented but I add it here anyway because it explains the things like like most with jmxmp in a few good sentences.
How to define the server side endpoint is depending on what you are running. Most app servers will let you type in a jmxmp enabled jmx service url but if the server is written from scratch you might have to set it up yourself in code instead of using the -D switches to java you are used to.
Give it a try and return with more specific questions about it if you run into problems.
Edit:
After you have added the jar to the classpath, the only thing you have to do in your code (assuming you are not using a server app that already handles it for you) is the following (omitting declarations, exception handling and such as you will figure it out anyway):
您是否尝试过从 Windows 计算机创建到 Linux 机器的 SSH 隧道? http://oldsite.precedence.co.uk/nc/putty.html
或者,如果您有 cygwin,只需尝试
ssh -f [电子邮件受保护] -L 7777:remote-server.com:123 -N
其中7777
是您的 Windows 计算机上的端口,123
是 Windows 计算机上的端口监听 JMX 命令的远程 Linux 盒子。通过以上任一方式,您可以在 Windows 机器上使用 jconsole 或 VisualVM 并连接到
localhost:7777
。我知道 iptables 已禁用,但只需通过 SSH 连接到 Linux 机器并尝试对 localhost 使用 jconsole 的命令行 JMX 模式(在 Linux 机器上)来确认 JMX 在该端口正常工作。
Have you tried creating an SSH tunnel to the Linux box from your Windows machine? http://oldsite.precedence.co.uk/nc/putty.html
Or if you have cygwin, just try
ssh -f [email protected] -L 7777:remote-server.com:123 -N
where7777
is the port on YOUR windows machine, and123
is the port on the remote Linux box that listens to JMX commands.With either of the above, you can use jconsole or visualvm on your Windows box and connect to
localhost:7777
.I know iptables is disabled, but just confirm that JMX is working fine at that port by SSHing into the Linux box and trying to use commandline JMX mode of jconsole for localhost (on the Linux box).
事实上,我自己刚刚解决了这个问题并找到了答案。
我敢打赌问题是 RMI 连接 - 您无法预测它将使用哪些端口,因此您无法让它与防火墙一起工作。
解决方法是使用 SSH 代理:
通过 SSH 连接到运行应用程序的机器,但使用 -D 选项,如下所示:
ssh user@remoteHost -D 9999
当您在 Windows 上时,您可以使用 Cygwin 运行上面的命令,或者您可以通过 GUI 使用 Putty 执行相同的操作(此处指南:http://blog.ashurex.com/2012/03/15/creating-ssh-proxy-tunnel-putty/< /a>)
这将在本地计算机上的端口 9999 上启动袜子代理。
打开 JVisualVM 并在首选项中的“网络”下将其配置为使用本地主机上端口 9999 上的袜子代理。
如果执行上述操作,您应该能够正常连接到远程计算机,因为所有 RMI 流量现在都通过 SSH 代理进行,它可以穿透防火墙并且运行良好。
祝你好运 :-)
I have actually just tackled this problem myself and figured it out.
I would wager that the problem is the RMI connections - you can't predict which ports it will use and so you can't get it to work with a firewall.
The workaround is to use an SSH proxy:
SSH to the box where your application is running but use the -D option like this:
ssh user@remoteHost -D 9999
As you are on Windows, you can use Cygwin to run the command above, or you can do the same thing with Putty through the GUI (guide here: http://blog.ashurex.com/2012/03/15/creating-ssh-proxy-tunnel-putty/)
This will start a socks proxy on your local machine on port 9999.
Open JVisualVM and in the preferences, under 'network' configure it to use a socks proxy at localhost, on port 9999.
If you do the above, you should then be able to connect to the remote machine as normal and since all the RMI traffic is now going over the SSH proxy, it is punched through the firewall and works nicely.
Good luck :-)