2008-12-01 9 views
17

В настоящее время я запускаю свою виртуальную машину Java с com.sun.management.jmxremote.* свойствами, чтобы я мог подключиться к нему через JConsole для управления и мониторинга. К сожалению, он прослушивает все интерфейсы (IP-адреса) на машине.Как связать JMX с конкретным интерфейсом?

В нашей среде часто бывают случаи, когда на машине одновременно работает более одной виртуальной машины Java. Хотя JMX можно прослушать на разных TCP-портах (используя com.sun.management.jmxremote.port), было бы неплохо, если бы JMX использовал стандартный порт JMX и просто привязывался к определенному IP-адресу (а не ко всем).

Это упростит определение того, с какой виртуальной машиной мы подключаемся через JConsole (поскольку каждая виртуальная машина фактически «владеет» своим собственным IP-адресом). Кто-нибудь понял, как заставить JMX прослушивать один IP-адрес или имя хоста?

ответ

15

Если кто-то будет терять свои нервы с этим ... Через 10 лет, они, наконец, установил ее!

Поскольку Java 8u102 -Dcom.sun.management.jmxremote.host связывается с выбранным IP

см: https://bugs.openjdk.java.net/browse/JDK-6425769

8

Фернандо уже предоставил ссылку на my blog post :) .. это не тривиально. Вы должны предоставить свой собственный RMIServerSocketFactoryImpl, который создает сокеты по желаемому адресу.

Если проблема связана с внутренними/внешними интерфейсами, и у вас есть локальный доступ, настройка локального межсетевого экрана может быть проще.

+0

Спасибо - я не думал, что это будет просто или красиво. :) – 2008-12-02 06:53:09

-3

Принятый ответ довольно старый. Есть некоторые признаки того, что Java теперь предоставляет некоторые опции для включения этого. Например, я видел:

-Djava.rmi.server.hostname=<YOUR_IP> 

... а также ...

-Dcom.sun.management.jmxremote.host=<YOUR_IP> 

Однако, по крайней мере, на моей системе под JDK 1.7, это, кажется, не имеют какой-либо эффект - Разъем JMX по-прежнему привязывается к *. Был бы весьма признателен обновленный ответ (с конкретными применимыми версиями). Это должно быть быть простым.

+0

Ни один из них не контролирует адрес привязки. `java.rmi.server.hostname` не является новым, он существует уже 17 лет, и я сомневаюсь, что он тоже новый. – EJP 2014-09-16 00:46:36

+0

Я не сказал, что они были новыми. Я сказал, что видел их, и они не сработали. – sosiouxme 2014-09-16 16:41:40

0

Я не пробовал, но это может помочь.

Главной неприятностью здесь было то, что нет простого способа указать адрес IP-адреса хоста IP-адреса для JMX для привязки, он всегда будет привязан ко всем интерфейсам. Свойство «java.rmi.server.hostname» не работает, и я не хотел выбирать различные порты для всех разных экземпляров на одном хосте.

Кроме того, я не хотел создавать свой собственный RMIServerSocketFactory со всеми связанными с ним сложностями , я был после простого исправления существующего кода.

Я исправил это, установив заводскую фабрику сокетов JMM по умолчанию, которая является , ответственным за создание этого серверного сокета. Теперь он поддерживает новое свойство 'com.sun.management.jmxremote.host'.

Чтобы заставить это работать, сохраните Java-код ниже в файле с именем sun/rmi/transport/proxy/RMIDirectSocketFactory.java.

Скомпилируйте и создайте jmx_patch.jar из него и поместите его в папку tomcat lib/ .

Затем нужно добавить следующую строку в бен/setenv.sh:

CLASSPATH = $ CLASSPATH: $ CATALINA_HOME/Библиотека/mx_patch.баночка

добавить эту опцию в TOMCAT случае запуска

-Dcom.sun.management.jmxremote.host = 192.168.100.100"

Это будет связать службу JMX только в адрес 192.168.100.100. в 2 других случайных RMI слушающих порты будут по-прежнему связывается со всеми интерфейсами, но это хорошо как они всегда выбирают свободный порт в любом случае.

Теперь вы можете запускать несколько экземпляров Tomcat на одном хосте со всеми портов по умолчанию неповрежденный (например, 8080 для JMX для все они).

package sun.rmi.transport.proxy; 

import java.io.IOException; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.rmi.server.RMISocketFactory; 

public class RMIDirectSocketFactory extends RMISocketFactory { 

    public Socket createSocket(String host, int port) throws IOException 
    { 
    return new Socket(host, port); 
    } 

    public ServerSocket createServerSocket(int port) throws IOException 
    { 
    String jmx_host = System.getProperty("com.sun.management.jmxremote.host"); 
    String jmx_port = System.getProperty("com.sun.management.jmxremote.port"); 

    // Allow JMX to bind to specific address 
    if (jmx_host != null && jmx_port != null && port != 0 && integer.toString(port).equals(jmx_port)) { 
    InetAddress[] inetAddresses = InetAddress.getAllByName(jmx_host); 
    if (inetAddresses.length > 0) { 
    return new ServerSocket(port, 50, inetAddresses[0]); 
    } 
} 

return new ServerSocket(port); 
    } 

}

0

Я просто попытался

-Dcom.sun.management.jmxremote.host =

с OpenJDK 1,8, и он работает хорошо. Он привязывается к этой добавке (согласно netstat), и все выглядит правильно (и работает).

 Смежные вопросы

  • Нет связанных вопросов^_^