Подтвердить что ты не робот

Как связать JMX с определенным интерфейсом?

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Я исправил это, установив по умолчанию JVM RMI-сокет factory, который ответственный за создание этого серверного сокета. Теперь он поддерживает новые Свойство com.sun.management.jmxremote.host.

Чтобы заставить это работать, сохраните код Java ниже в файл с именем ВС/RMI/транспорт/прокси/RMIDirectSocketFactory.java.

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

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

CLASSPATH = $CLASSPATH: $CATALINA_HOME/Library/mx_patch.jar

добавить эту опцию в запуск экземпляра 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);
  }

}

Ответ 4

Я просто попробовал

-Dcom.sun.management.jmxremote.host =

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

Ответ 5

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

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

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

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

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