为什么在配置 JMX 时 Java 会打开 3 个端口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20884353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why Java opens 3 ports when JMX is configured?
提问by Michael
I run my Java program with JDK7 on Centos6. I enable JMX using the following options:
我在 Centos6 上使用 JDK7 运行我的 Java 程序。我使用以下选项启用 JMX:
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true"
When I check what ports are opened I discover 2 additional random ports:
当我检查打开了哪些端口时,我发现了 2 个额外的随机端口:
netstat -plunt | grep java
tcp 0 0 :::9123 :::* LISTEN 13295/java
tcp 0 0 :::59927 :::* LISTEN 13295/java
tcp 0 0 :::59928 :::* LISTEN 13295/java
Please note that each restart only configured port 9123 remains same, and two additional ports change values.
请注意,每次重启仅配置的端口 9123 保持不变,另外两个端口更改值。
netstat -plunt | grep java
tcp 0 0 :::9123 :::* LISTEN 13331/java
tcp 0 0 :::59932 :::* LISTEN 13331/java
tcp 0 0 :::59933 :::* LISTEN 13331/java
What are 2 additional ports and why they are opened?
什么是 2 个额外的端口,为什么要打开它们?
How can I configure 2 additional random ports?
如何配置 2 个额外的随机端口?
How can I configure ::ffff:127.0.0.1
will appear before all ports opened by JMX?
如何配置::ffff:127.0.0.1
将出现在 JMX 打开的所有端口之前?
Why one port is not used when connecting with JConsole?
为什么在连接 JConsole 时不使用一个端口?
Added to clarify the answer
添加以澄清答案
Unfortunately, the additional random port is still opened To remind you, I use Centos 6. My Tomcat settings are look like this (Tomcat does not deploy any applications):
不幸的是,额外的随机端口仍然打开提醒您,我使用Centos 6。我的Tomcat设置如下(Tomcat不部署任何应用程序):
CATALINA_OPTS="${CATALINA_OPTS} -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true -Djava.rmi.server.useLocalHostname=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.rmi.port=9123"
Tomcat process looks like this:
Tomcat 进程如下所示:
/usr/java/jdk1.7.0_51/bin/java -Djava.util.logging.config.file=/usr/tomcat-7.0.47/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true -Djava.rmi.server.useLocalHostname=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.rmi.port=9123 -Djava.endorsed.dirs=/usr/tomcat-7.0.47/endorsed -classpath /usr/tomcat-7.0.47/bin/bootstrap.jar:/usr/tomcat-7.0.47/bin/tomcat-juli.jar -Dcatalina.base=/usr/tomcat-7.0.47 -Dcatalina.home=/usr/tomcat-7.0.47 -Djava.io.tmpdir=/usr/tomcat-7.0.47/temp org.apache.catalina.startup.Bootstrap start
Unfortunately, each time I see additional listening port:
不幸的是,每次我看到额外的监听端口:
tcp 0 0 :::38830 :::* LISTEN 790/java
tcp 0 0 ::ffff:127.0.0.1:8080 :::* LISTEN 790/java
tcp 0 0 :::9123 :::* LISTEN 790/java
Additional run:
额外运行:
tcp 0 0 ::ffff:127.0.0.1:8080 :::* LISTEN 2348/java
tcp 0 0 :::36252 :::* LISTEN 2348/java
tcp 0 0 :::9123 :::* LISTEN 2348/java
BTW, why I can not see ::ffff:127.0.0.1
before RMI ports?
BTW,为什么我::ffff:127.0.0.1
之前看不到RMI端口?
Added second time to clarify the comment
添加第二次以澄清评论
It is not related to Tomcat. I have tried to run ant with similar settings: Ant process looks like this:
它与Tomcat无关。我曾尝试使用类似的设置运行 ant:Ant 进程如下所示:
/usr/bin/java -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true -Djava.rmi.server.useLocalHostname=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.rmi.port=9123 -classpath /usr/apache-ant-1.9.2/lib/ant-launcher.jar -Dant.home=/usr/apache-ant-1.9.2 -Dant.library.dir=/usr/apache-ant-1.9.2/lib org.apache.tools.ant.launch.Launcher -cp sleep
Unfortunately, each time I see additional listening port:
不幸的是,每次我看到额外的监听端口:
tcp 0 0 :::41200 :::* LISTEN 13597/java
tcp 0 0 :::9123 :::* LISTEN 13597/java
Additional run:
额外运行:
tcp 0 0 :::58356 :::* LISTEN 13629/java
tcp 0 0 :::9123 :::* LISTEN 13629/java
Answer: It is Java's bug
答:这是Java的bug
I success to open bug on Java: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404
我成功在 Java 上打开错误:http: //bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404
采纳答案by peterh
Contrary to common belief JMX/RMI doesn't need to open all these ports. You can actually force them to be same which will mean that at the end of the day you'll only need to punch one hole in the firewall (if firewall is your concern).
与普遍看法相反,JMX/RMI 不需要打开所有这些端口。您实际上可以强制它们相同,这意味着在一天结束时您只需要在防火墙上打一个洞(如果防火墙是您的问题)。
Try setting System Properties:
尝试设置系统属性:
com.sun.management.jmxremote.port
com.sun.management.jmxremote.rmi.port
to the same value!!
到相同的价值!!
Explicitly setting these will stop RMI from picking random ports. Setting them to the same value will make sure it opens less ports to listen on.
显式设置这些将阻止 RMI 选择随机端口。将它们设置为相同的值将确保它打开更少的端口来侦听。
This will work in Java 7 update 25 or later.
这将适用于 Java 7 update 25 或更高版本。
What is the third port?
第三个端口是什么?
The third port that you see opened by your application (or the second if you followed my advice above) is used by the Java Attach API. It is what JConsole uses for connecting to "Local Process". The Java Attach API feature is enabled by default since Java 6 regardless of the com.sun.management.jmxremote
property. This feature will use a random port (aka an OS ephemeral port) but it really doesn't matter because the feature only allows connections from the host itself. If you really dislike this feature then you can add -XX:+DisableAttachMechanism
to the command line to disable the Java Attach API feature. Then you'll no longer see the java process (in this case Tomcat) listening on a random port.
您看到的应用程序打开的第三个端口(如果您遵循我上面的建议,则为第二个端口)由Java Attach API 使用。JConsole 使用它来连接到“本地进程”。从 Java 6 开始,默认情况下启用 Java 附加 API 功能,无论com.sun.management.jmxremote
属性如何。此功能将使用随机端口(也称为 OS 临时端口),但这并不重要,因为该功能仅允许来自主机本身的连接。如果您真的不喜欢此功能,则可以添加-XX:+DisableAttachMechanism
到命令行以禁用 Java 附加 API 功能。然后您将不再看到 java 进程(在本例中为 Tomcat)监听随机端口。
How do I make JMX listen on the loopback interface only
如何让 JMX 只在环回接口上监听
With a custom made application you would use a RMIServerSocketFactorybut this is Tomcat so you would have to do it using Tomcat's JMX Remote Lifecycle Listener.
对于定制的应用程序,您将使用RMIServerSocketFactory但这是 Tomcat,因此您必须使用 Tomcat 的JMX Remote Lifecycle Listener 来完成。
On the other hand it doesn't matter now that you have the com.sun.management.jmxremote.local.only
property since Java 7. It makes sure that only connections from the host itself are allowed. Mind you that JMX library doesn't achieve this by binding to loopback interface which would certainly be oneway of doing it but also slight inaccurate as a host can potentially have several loopback interfaces.
另一方面,com.sun.management.jmxremote.local.only
自 Java 7 以来您拥有该属性并不重要。它确保只允许来自主机本身的连接。请注意,JMX 库并没有通过绑定到回送接口来实现这一点,这当然是一种实现方式,但由于主机可能具有多个回送接口,因此有点不准确。
In fact by and large (with the most recent additions to JDK wrt JMX) I would say that Tomcat's JMX Remote Lifecycle Listeneris now redundant except if you want to bind to some really odd network interface.
事实上,总的来说(最近添加到 JDK wrt JMX)我会说 Tomcat 的JMX 远程生命周期监听器现在是多余的,除非你想绑定到一些非常奇怪的网络接口。
回答by fbacchella
Because jmx is encapsulated in rmi wich is very firewall and nat unfriendly. Avoid it if you can, there is an alternative encapsulation called jmxmp.
因为 jmx 被封装在 rmi 中,这对防火墙和 nat 非常不友好。如果可以,请避免使用它,还有一种称为 jmxmp 的替代封装。
Have a look at, that might help you : http://blog.markfeeney.com/2010/10/jmx-through-ssh-tunnel.htmlhttp://jrds.fr/sourcetype/jmx/start#jmx_protocols
看看,这可能对你有帮助:http: //blog.markfeeney.com/2010/10/jmx-through-ssh-tunnel.html http://jrds.fr/sourcetype/jmx/start#jmx_protocols
回答by user2679436
Using Oracle Java SE 1.8.0_121.
使用 Oracle Java SE 1.8.0_121。
It's possible to set jmxremote.port and jmxremote.rmi.port to the same value, it's one less port opened. It's also possible to set jmxremote.host=127.0.0.1, to have that port (or those two ports, if you set them differently) bind to the loopback interface only.
可以将 jmxremote.port 和 jmxremote.rmi.port 设置为相同的值,少打开一个端口。也可以设置 jmxremote.host=127.0.0.1,使该端口(或这两个端口,如果设置不同)仅绑定到环回接口。
Another port is still dynamically assigned though, and will bind to 0.0.0.0. I was not able to prevent this port with -XX+DisableAttachMechanism, and was also unable to make it bind to anything else than 0.0.0.0.
另一个端口仍然是动态分配的,并将绑定到 0.0.0.0。我无法使用 -XX+DisableAttachMechanism 阻止此端口,也无法将其绑定到 0.0.0.0 以外的任何其他内容。