JMX端口

2023/07/04

1. 概述

在本教程中,我们将解释为什么JMX在启动时打开三个端口。此外,我们将展示如何在Java中启动JMX。之后,我们将展示如何限制打开的端口数。

2. JMX定义

让我们首先定义什么是JMX框架。Java Management Extensions(JMX)框架为管理Java应用程序提供了一个可配置、可伸缩且可靠的基础结构。此外,它还为应用程序的实时管理定义了MBean的概念。该框架允许在本地或远程管理应用程序。

3. 在Java中启用JMX

现在让我们来看看如何启用JMX,对于Java 1.5及之前的版本,有一个系统属性com.sun.management.jmxremote。使用该属性启动的应用程序允许从本地和远程连接JConsole。另一方面,在没有该属性的情况下启动应用程序时,从JConsole中是不可见的。

但是,从Java 6及以上版本开始,该参数就不再需要了。启动后,应用程序自动可用于管理。此外,默认配置会自动分配端口并仅在本地公开。

4. JMX端口

在我们的示例中,我们将使用Java 6或更高版本。首先,让我们创建一个具有无限循环的类,该类什么都不做,但它允许我们检查打开了哪些端口:

public class JMXConfiguration {

    public static void main(String[] args) {
        while (true) {
            // to ensure application does not terminate
        }
    }
}

现在,我们将编译类并启动它:

java cn.tuyucheng.taketoday.jmx.JMXConfiguration

之后,我们可以检查分配给进程的pid并检查进程打开的端口

netstat -ao | grep <pid>

结果,我们将获得应用程序公开的端口列表:

Active Connections
Proto  Local Address          Foreign Address        State           PID
TCP    127.0.0.1:55846        wujek:55845            ESTABLISHED     2604

此外,在重启的情况下,端口将会改变,它是随机分配的。此功能从Java 6开始可用,它自动为Java Attach API公开应用程序。换句话说,它通过本地进程自动公开JConsole连接的应用程序。

现在让我们通过向JVM提供选项来启用远程连接:

-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

端口号是我们必须提供的强制参数,以便为远程连接公开JMX。我们仅出于测试目的禁用身份验证和SSL。

现在,netstat命令返回:

Proto  Local Address    Foreign Address State       PID
TCP    0.0.0.0:1234     wujek:0         LISTENING   11088
TCP    0.0.0.0:58738    wujek:0         LISTENING   11088
TCP    0.0.0.0:58739    wujek:0         LISTENING   11088

如我们所见,该应用程序公开了三个端口。RMI/JMX公开了两个端口,第三个是用于本地连接的随机端口。

5. 限制开放端口数

首先,我们可以使用-XX:+DisableAttachMechanism选项禁用从JConsole公开本地连接的应用程序:

java -XX:+DisableAttachMechanism cn.tuyucheng.taketoday.jmx.JMXConfiguration

之后,应用程序不会公开任何JMX/RMI端口。

此外,从JDK 16开始,我们可以设置本地端口号

java 
  -Dcom.sun.management.jmxremote=true 
  -Dcom.sun.management.jmxremote.local.port=1235 
  cn.tuyucheng.taketoday.jmx.JMXConfiguration

现在让我们更改配置并使用远程端口。

还有一个附加选项-Dcom.sun.management.jmxremote.rmi.port=1234允许我们将RMI端口设置为与JMX端口相同的值。现在,完整的命令是:

java 
  -Dcom.sun.management.jmxremote=true 
  -Dcom.sun.management.jmxremote.port=1234 
  -Dcom.sun.management.jmxremote.rmi.port=1234 
  -Dcom.sun.management.jmxremote.local.port=1235 
  -Dcom.sun.management.jmxremote.authenticate=false 
  -Dcom.sun.management.jmxremote.ssl=false 
  cn.tuyucheng.taketoday.jmx.JMXConfiguration

之后,netstat命令返回:

Proto  Local Address    Foreign Address State       PID
TCP    0.0.0.0:1234     wujek:0         LISTENING   19504
TCP    0.0.0.0:1235     wujek:0         LISTENING   19504

也就是说,应用程序只暴露两个端口,一个用于JMX/RMI远程连接,一个用于本地连接。得益于此,我们可以完全控制暴露的端口,避免与其他进程暴露的端口发生冲突。

但是,当我们启用远程连接并禁用附加机制时:

java 
  -XX:+DisableAttachMechanism 
  -Dcom.sun.management.jmxremote=true 
  -Dcom.sun.management.jmxremote.port=1234 
  -Dcom.sun.management.jmxremote.rmi.port=1234 
  -Dcom.sun.management.jmxremote.authenticate=false 
  -Dcom.sun.management.jmxremote.ssl=false 
  cn.tuyucheng.taketoday.jmx.JMXConfiguration

然后,应用程序仍然暴露两个端口:

Proto Local Address     Foreign Address     State       PID
TCP   0.0.0.0:1234      wujek:0             LISTENING   9856
TCP   0.0.0.0:60565     wujek:0             LISTENING   9856

6. 总结

在这篇简短的文章中,我们解释了如何在Java中启动JMX。然后,我们展示了JMX在启动时打开了哪些端口。最后,我们介绍了如何限制JMX打开的端口数。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章