1. Overview
1.概述
In this tutorial, we’ll explain why JMX opens three ports on startup. Additionally, we’ll show how to start JMX in Java. Afterward, we’ll show how to limit the number of opened ports.
在本教程中,我们将解释为什么JMX在启动时打开三个端口。此外,我们将展示如何在Java中启动JMX。之后,我们将展示如何限制打开的端口的数量。
2. JMX Definition
2.JMX定义
Let’s first define what the JMX framework is. The Java Management Extensions (JMX) framework provides a configurable, scalable, and reliable infrastructure for managing Java applications. Furthermore, it defines a concept of MBean for real-time management of the application. The framework allows managing an application locally or remotely.
我们首先来定义一下什么是JMX框架。Java Management Extensions (JMX) 框架为管理Java应用程序提供了一个可配置、可扩展和可靠的基础设施。此外,它还定义了一个MBean的概念,以便对应用程序进行实时管理。该框架允许在本地或远程管理一个应用程序。
3. Enable JMX in Java
3.在Java中启用JMX
Let’s now have a look at how to enable JMX. For Java version 1.5 and previous, there is a system property com.sun.management.jmxremote. An application started with that property allows connecting with JConsole from local and from remote. On the other hand, an application is not visible from JConsole when started without the property.
现在让我们来看看如何启用JMX。对于Java 1.5及以前的版本,有一个系统属性com.sun.management.jmxremote。使用该属性启动的应用程序允许从本地和远程与JConsole连接。另一方面,当一个应用程序在没有该属性的情况下启动时,从JConsole中是不可见的。
However, starting from Java 6 and above, the parameter is unnecessary. The application is automatically available for management after startup. Furthermore, the default configuration assigns the port automatically and exposes it only locally.
然而,从Java 6及以上版本开始,该参数是不必要的。该应用程序在启动后可自动用于管理。此外,默认配置会自动分配端口并只在本地公开。
4. JMX Ports
4.JMX端口
In our examples, we’ll use Java 6 or higher. First, let’s create a class with an infinite loop. The class is doing nothing, but it allows us to check which ports are opened:
在我们的例子中,我们将使用Java 6或更高版本。首先,让我们创建一个具有无限循环的类。这个类什么也不做,但它允许我们检查哪些端口已经打开。
public class JMXConfiguration {
public static void main(String[] args) {
while (true) {
// to ensure application does not terminate
}
}
}
Now, we’ll compile the class and start it:
现在,我们将编译这个类并启动它。
java com.baeldung.jmx.JMXConfiguration
After that, we can check which pid is assigned to the process and check ports opened by the process:
之后,我们可以检查哪个pid被分配给进程,并检查该进程打开的端口。
netstat -ao | grep <pid>
As a result, we’ll get a list of ports exposed by our application:
因此,我们将得到一个由我们的应用程序暴露的端口列表。
Active Connections
Proto Local Address Foreign Address State PID
TCP 127.0.0.1:55846 wujek:55845 ESTABLISHED 2604
In addition, in case of a restart, the port will change. It is assigned randomly. This functionality has been available since Java 6, which automatically exposes the application for the Java Attach API. In other words, it automatically exposes the application for JConsole connection via Local Process.
此外,在重新启动的情况下,端口将改变。它是随机分配的。这个功能从Java 6开始就有了,它自动将应用程序暴露给Java Attach API。换句话说,它自动为通过本地进程的JConsole连接公开应用程序。
Let’s now enable remote connections by providing options to the JVM:
现在让我们通过向JVM提供选项来启用远程连接。
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
The port number is a mandatory parameter we must provide in order to expose JMX for remote connection. We disabled authentication and SSL only for testing purposes.
端口号是我们必须提供的一个参数,以便将JMX暴露于远程连接。我们禁用认证和SSL只是为了测试的目的。
Now, the netstat command returns:
现在,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
As we can see, the application exposed three ports. RMI/JMX exposes two ports. The third one is a random port for a local connection.
我们可以看到,该应用程序暴露了三个端口。RMI/JMX暴露了两个端口。第三个是一个用于本地连接的随机端口。
5. Limit Number of Ports Opened
5.限制打开的端口数量
First of all, we can disable exposing an application for local connection from JConsole with the -XX:+DisableAttachMechanism option:
首先,我们可以用-XX:+DisableAttachMechanism选项禁止从JConsole暴露一个应用程序的本地连接。
java -XX:+DisableAttachMechanism com.baeldung.jmx.JMXConfiguration
After that, the application doesn’t expose any JMX/RMI ports.
此后,该应用程序不再暴露任何JMX/RMI端口。
Furthermore, starting from JDK 16, we can set the local port number:
此外,从JDK 16开始,我们可以设置本地端口号。
java
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.port=1235
com.baeldung.jmx.JMXConfiguration
Let’s now change the configuration and play with remote ports.
现在让我们改变配置,玩玩远程端口。
There’s an additional option -Dcom.sun.management.jmxremote.rmi.port=1234 that allows us to set the RMI port to the same value as the JMX port. Now, the full command is:
有一个额外的选项-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
com.baeldung.jmx.JMXConfiguration
After that, the netstat command returns:
之后,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
That is to say, the application exposes only two ports, one for the JMX/RMI remote connection and one for the local connection. Thanks to that, we can fully control exposed ports and avoid conflicts with ports exposed by other processes.
也就是说,应用程序只暴露了两个端口,一个用于JMX/RMI远程连接,一个用于本地连接。得益于此,我们可以完全控制暴露的端口,避免与其他进程暴露的端口冲突。
However, when we enable connection from remote and disable the attach mechanism:
然而,当我们启用远程连接并禁用附加机制时。
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
com.baeldung.jmx.JMXConfiguration
Then, the application still exposes two ports:
然后,该应用程序仍然暴露了两个端口。
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. Conclusion
6.结语
In this short article, we explained how to start JMX in Java. Then, we showed which ports are opened by JMX on startup. Finally, we presented how to limit the number of ports opened by JMX.
在这篇短文中,我们解释了如何在Java中启动JMX。然后,我们展示了JMX在启动时打开了哪些端口。最后,我们介绍了如何限制JMX打开的端口数量。
As always, the source code of the example is available over on GitHub.
一如既往,该示例的源代码可在GitHub上获得over。