Ответ 1
По умолчанию JMX автоматически доступен локально, поэтому запуск jconsole
локально обнаруживает все ваши локальные приложения Java без воздействия порта.
Чтобы получить доступ к приложению через JMX удаленно, вы должны указать порт реестра RMI. Дело в том, что при подключении JMX инициализирует этот порт и , а затем устанавливает соединение с данными на случайном высоком порту, что является огромной проблемой, если у вас есть межсетевой экран посередине. ( "Эй, сидэдмины, просто откройте все, mkay?" ).
Чтобы заставить JMX подключиться обратно к тому же порту, который вы установили, у вас есть несколько вариантов:
Вариант 1: Командная строка
-Dcom.sun.management.jmxremote.port=$JMX_REGISTRY_PORT
-Dcom.sun.management.jmxremote.rmi.port=$RMI_SERVER_PORT
Если вы используете Spring Boot, вы можете поместить это в свой (appname).conf
файл, который живет рядом с развертыванием (appname).jar
.
Вариант 2: Конфигурация Tomcat/Tomee
Настроить JmxRemoteLifecycleListener:
Maven Jar:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina-jmx-remote</artifactId>
<version>8.5.9</version>
<type>jar</type>
</dependency>
Настройте свой server.xml:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />
Вариант 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;
}
}
Трюк, вы увидите, это serviceUrl
, в котором вы указываете как хост/порт jmx: rmi, так и хост/порт jndi: rmi. Если вы укажете оба варианта, вы не получите случайную высокую "проблему".