连接服务器上的jmx
解释远程 JMX 访问失败时 java.rmi.server.hostname 与 Linux hostname 的关系。
在有公网ip的服务器上,部署一个Java服务,开启jmx端口,但是却不能通过公网ip访问。为什么呢?
方法一:java.rmi.server.hostname
查到的第一种解决方式:使用java.rmi.server.hostname参数手动绑定到外网ip:
- Oracle RMI properties: java.rmi.server.hostname
- Stack Overflow: JMX remote hostname 配置
- Stack Overflow: 指定 JMX/RMI hostname
即:
1
-Djava.rmi.server.hostname=<external ip>
方法二:修改hostname为外网ip
远程访问,就是得设定hostname:
一整篇都在讨论这个问题,我猜是
按照这个人说的把hostname改成ip而非loop ip后,无需再指定java.rmi.server.hostname参数也能远程访问jmx:
修改hostname为ip:
1
sudo hostname <external ip>
所以猜想:其实jmx默认是绑定到hostname上的。所以要么让hostname是外网可用的ip,要么让jmx不绑定到默认的hostname上,使用参数手动指定一个。
flowchart TD
Client["JConsole / jmx client"] --> Registry["连接 JMX/RMI registry 端口"]
Registry --> Stub["返回 RMI stub"]
Stub --> Addr["stub 内带 server hostname/IP"]
Addr -->|是 localhost / 内网不可达地址| Fail["客户端继续连接失败"]
Addr -->|是 external ip / 可解析域名| OK["连接真正的 RMI 对象"]
Fix1["-Djava.rmi.server.hostname=<external ip>"] --> Addr
Fix2["hostname 解析成外网可达地址"] --> Addr
这里最坑的点是:JMX不是只连一次端口就完事儿,RMI会把服务端地址塞进返回的stub里。所以端口能通不代表最终能连上;如果stub里写的是localhost或者一台客户端根本到不了的内网名,客户端就会一脸懵逼地去连一个错误地址。
本文由作者按照 CC BY 4.0 进行授权