文章

连接服务器上的jmx

解释远程 JMX 访问失败时 java.rmi.server.hostname 与 Linux hostname 的关系。

在有公网ip的服务器上,部署一个Java服务,开启jmx端口,但是却不能通过公网ip访问。为什么呢?

  1. 方法一:java.rmi.server.hostname
  2. 方法二:修改hostname为外网ip

方法一:java.rmi.server.hostname

查到的第一种解决方式:使用java.rmi.server.hostname参数手动绑定到外网ip:

即:

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 进行授权