Как связать JMX с определенным интерфейсом? - PullRequest
19 голосов
/ 01 декабря 2008

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

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

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

Ответы [ 5 ]

22 голосов
/ 06 сентября 2016

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

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

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

8 голосов
/ 02 декабря 2008

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

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

0 голосов
/ 20 марта 2017

Я только что попробовал

-Dcom.sun.management.jmxremote.host =

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

0 голосов
/ 09 августа 2016

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

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

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

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

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

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

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

CLASSPATH = $ CLASSPATH: $ CATALINA_HOME / Библиотека / 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);
  }

}

0 голосов
/ 15 сентября 2014

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

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

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

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

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

...