如何远程访问 Spring-boot JMX
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29412072/
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
How to access Spring-boot JMX remotely
提问by rayman
I know that spring automatically expose JMX beans. I was able to access it locally using VisualVM.
我知道 spring 会自动公开 JMX bean。我能够使用 VisualVM 在本地访问它。
However on prod how I can connect to remotely to the app using it's JMX beans? Is there a default port or should I define anything in addition?
但是,在 prod 上,我如何使用它的 JMX bean 远程连接到应用程序?是否有默认端口或者我应该另外定义什么?
Thanks, ray.
谢谢,雷。
回答by inanutshellus
By default JMX is automatically accessible locally, so running jconsole
locallywould detect all your local java apps without port exposure.
默认情况下,JMX 可在本地自动访问,因此在jconsole
本地运行将检测所有本地 Java 应用程序,而不会暴露端口。
To access an app via JMX remotelyyou have to specify an RMI Registry port. The thing to know is that when connecting, JMX initializes on that port and thenestablishes a data connection back on a random highport, which is a huge problem if you have a firewall in the middle. ("Hey sysadmins, just open up everything, mkay?").
要通过 JMX远程访问应用程序,您必须指定一个 RMI 注册表端口。要知道的是,在连接时,JMX 在该端口上初始化,然后在随机的高端口上建立数据连接,如果中间有防火墙,这是一个大问题。(“嘿系统管理员,打开所有东西,好吗?”)。
To force JMX to connect back on the same port as you've established, you have a couple options:
要强制 JMX 在您建立的同一端口上重新连接,您有几个选项:
Option 1: Command line
选项 1:命令行
-Dcom.sun.management.jmxremote.port=$JMX_REGISTRY_PORT
-Dcom.sun.management.jmxremote.rmi.port=$RMI_SERVER_PORT
If you're using Spring Boot you can put this in your (appname).conf
file that lives alongside your (appname).jar
deployment.
如果您使用的是 Spring Boot,则可以将其放在(appname).conf
与(appname).jar
部署一起存在的文件中。
Option 2: Tomcat/Tomee configuration
选项 2:Tomcat/Tomee 配置
Configure a JmxRemoteLifecycleListener:
配置一个JmxRemoteLifecycleListener:
Maven Jar:
Maven 罐子:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina-jmx-remote</artifactId>
<version>8.5.9</version>
<type>jar</type>
</dependency>
Configure your server.xml:
配置你的 server.xml:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />
Option 3: configure programmatically
选项 3:以编程方式配置
@Configuration
public class ConfigureRMI {
@Value("${jmx.rmi.host:localhost}")
private String rmiHost;
@Value("${jmx.rmi.port:1099}")
private Integer rmiPort;
@Bean
public RmiRegistryFactoryBean rmiRegistry() {
final RmiRegistryFactoryBean rmiRegistryFactoryBean = new RmiRegistryFactoryBean();
rmiRegistryFactoryBean.setPort(rmiPort);
rmiRegistryFactoryBean.setAlwaysCreate(true);
return rmiRegistryFactoryBean;
}
@Bean
@DependsOn("rmiRegistry")
public ConnectorServerFactoryBean connectorServerFactoryBean() throws Exception {
final ConnectorServerFactoryBean connectorServerFactoryBean = new ConnectorServerFactoryBean();
connectorServerFactoryBean.setObjectName("connector:name=rmi");
connectorServerFactoryBean.setServiceUrl(String.format("service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi", rmiHost, rmiPort, rmiHost, rmiPort));
return connectorServerFactoryBean;
}
}
The trick, you'll see, is the serviceUrl
in which you specify both the jmx:rmi host/port and the jndi:rmi host/port. If you specify both, you won't get the random high "problem".
您将看到,诀窍在于serviceUrl
指定 jmx:rmi 主机/端口和 jndi:rmi 主机/端口。如果您同时指定两者,您将不会遇到随机高“问题”。
回答by Arnab Biswas
Add the following JVM Properties in "$JAVA_OPTS" (in your application):
在“$JAVA_OPTS”(在您的应用程序中)中添加以下 JVM 属性:
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=<PORT_NUMBER> -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=<HOST'S_IP>
In the Jconsole/Visual VM use the following to connect:
在 Jconsole/Visual VM 中,使用以下命令进行连接:
service:jmx:rmi:///jndi/rmi://<HOST'S_IP>:<PORT_NUMBER>/jmxrmi
It doesn't enable security, but will help you to connect to the remote server.
它不会启用安全性,但会帮助您连接到远程服务器。
回答by Popeye
A tested approach on Java 1.8.0_71 and Spring Boot(1.3.3.RELEASE). Append below parameters to JVM arguments for monitored JVM.
在 Java 1.8.0_71 和 Spring Boot(1.3.3.RELEASE) 上经过测试的方法。将以下参数附加到受监控 JVM 的 JVM 参数。
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12348 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.rmi.port=12349 -Dcom.sun.management.jmxremote.password.file=/somewhere/jmxremote.password -Dcom.sun.management.jmxremote.access.file=/somewhere/jmx/jmxremote.access
The com.sun.management.jmxremote.port
is used to define the fixed RMI registry port, and the com.sun.management.jmxremote.rmi.port
is used to instruct JVM to use fixed RMI port, but NOT use random one.
将com.sun.management.jmxremote.port
用于定义固定的RMI注册表端口,com.sun.management.jmxremote.rmi.port
用于指示JVM使用固定的RMI端口,而不是使用随机的。
By setting this, I am able to connect JVM client from remote host to the monitored JVM via a firewall just opening 12348 and 12349 port.
通过设置这一点,我可以通过防火墙将 JVM 客户端从远程主机连接到受监控的 JVM,只需打开 12348 和 12349 端口。
I tested using java -jar cmdline-jmxclient-0.10.3.jar user:pwd hostip:12348
on a remote machine, which generates below output(shortened just for demonstration).
我java -jar cmdline-jmxclient-0.10.3.jar user:pwd hostip:12348
在远程机器上进行了测试,它生成以下输出(仅为演示而缩短)。
java.lang:type=Runtime
java.lang:name=PS Scavenge,type=GarbageCollector
Tomcat:J2EEApplication=none,J2EEServer=none,WebModule=//localhost/,j2eeType=Filter,name=requestContextFilter
java.nio:name=mapped,type=BufferPool
Tomcat:host=localhost,type=Host
java.lang:name=Compressed Class Space,type=MemoryPool
.......
The jar is downloaded from Here.
该 jar 是从Here下载的。