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

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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
22
0
21 244
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

Спасибо - не думал, что это будет просто или красиво. :)

Marc Novakowski 02.12.2008 09:53

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

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

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

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

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

Ни один из них не управляет адресом привязки. java.rmi.server.hostname не новый, он существует уже 17 лет, и я сомневаюсь, что другой тоже новый.

user207421 16.09.2014 04:46

Я не сказал, что они новые. Я сказал, что видел их, и они не работали.

sosiouxme 16.09.2014 20:41

Я надеялся, что есть какой-то способ, который действительно работает, но не ужасен. Хотя не нашел.

sosiouxme 16.09.2014 20:55

Вы сказали: «Java Теперь предоставляет». Java всегда предоставляла java.rmi.server.hostname. Они действительно работают. Они просто не делают того, что вы думали. Вы также сказали, что «есть некоторые признаки» того, что они делают то, что вы думали, хотя это не так. Трудно понять смысл этого ответа.

user207421 17.09.2014 01:22

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

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

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

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

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

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

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

CLASSPATH = $ CLASSPATH: $ CATALINA_HOME / lib / 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);
  }

}

Ответ принят как подходящий

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

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

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

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

-Dcom.sun.management.jmxremote.host =

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

Это повторяющийся ответ - может быть, вы хотели добавить комментарий к исходному ответу?

Richlv 23.01.2018 00:10

Другие вопросы по теме