Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Spring-boot JMX remotely

I know that spring automatically expose JMX beans. I was able to access it locally using 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?

Thanks, ray.

like image 879
rayman Avatar asked Apr 02 '15 11:04

rayman


People also ask

How do I connect to a JMX Remote?

Remote JMX ConnectionsRight click anywhere in the blank area under the application tree and select Add JMX Connection. Provide the machine name and port number for a running JMX agent, that has been started with the appropriate system properties to allow remote management.

How do I enable JMX in spring boot?

JMX is automatically enabled by default in a Spring Boot application. As a result, all of the Actuator endpoints are exposed as MBeans. And it sets us up nicely to expose any other bean in the Spring application context as an MBean.

What is JMX remote port?

Enables the JMX remote agent and creates a remote JMX connector to listen through the specified port. By default, the SSL, password, and access file properties are used for this connector. It also enables local monitoring as described for the com.

How do I access JMX console?

The console is accessible at http://localhost:8080/jmx-console. The JMX Console provides a raw view of the JMX MBeans which make up the server.


1 Answers

By default JMX is automatically accessible locally, so running jconsole locally would detect all your local java apps without port exposure.

To access an app via JMX remotely you have to specify an RMI Registry port. The thing to know is that when connecting, JMX initializes on that port and then establishes a data connection back on a random high port, which is a huge problem if you have a firewall in the middle. ("Hey sysadmins, just open up everything, mkay?").

To force JMX to connect back on the same port as you've established, you have a couple of the following options. Note: you can use different ports for JMX and RMI or you can use the same port.

Option 1: Command line

-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.

Option 2: Tomcat/Tomee configuration

Configure a JmxRemoteLifecycleListener:

Maven Jar:

    <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:

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"       rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" /> 

Option 3: configure programmatically

@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".

Edit: For JMX remoting to work, you'll need to make a decision about authenticating. It's better to do it in 3 distinct steps: 1) basic setup with -Dcom.sun.management.jmxremote.authenticate=false then 2) add a password file (-Dcom.sun.management.jmxremote.password.file). See here for instructions. + -Dcom.sun.management.jmxremote.ssl=false and then 3) set up SSL.

like image 149
inanutshellus Avatar answered Sep 17 '22 14:09

inanutshellus