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




Фернандо уже предоставил ссылку на мой пост в блоге :) .. это нетривиально. Вы должны предоставить свой собственный RMIServerSocketFactoryImpl, который создает сокеты по желаемому адресу.
Если проблема связана с внутренними / внешними интерфейсами и у вас есть локальный доступ, настройка локального брандмауэра может быть проще.
Принятый ответ довольно старый. Есть некоторые признаки того, что Java теперь предоставляет некоторые параметры, позволяющие это сделать. Например, я видел:
-Djava.rmi.server.hostname=<YOUR_IP>
...а также...
-Dcom.sun.management.jmxremote.host=<YOUR_IP>
Однако, по крайней мере, в моей системе под jdk 1.7 это, похоже, не имеет никакого эффекта - коннектор JMX по-прежнему привязан к *. Был бы очень признателен обновленный ответ (с конкретными применимыми версиями). Это должен быть простым.
Ни один из них не управляет адресом привязки. java.rmi.server.hostname не новый, он существует уже 17 лет, и я сомневаюсь, что другой тоже новый.
Я не сказал, что они новые. Я сказал, что видел их, и они не работали.
Я надеялся, что есть какой-то способ, который действительно работает, но не ужасен. Хотя не нашел.
Вы сказали: «Java Теперь предоставляет». Java всегда предоставляла java.rmi.server.hostname. Они действительно работают. Они просто не делают того, что вы думали. Вы также сказали, что «есть некоторые признаки» того, что они делают то, что вы думали, хотя это не так. Трудно понять смысл этого ответа.
Я не пробовал, но это может помочь.
основная неприятность заключалась в том, что нет простого способа указать 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
Я только что попробовал
-Dcom.sun.management.jmxremote.host =
с openjdk 1.8, и он хорошо работает. Он привязывается к этому адресу (согласно netstat), и все выглядит правильно (и работает).
Это повторяющийся ответ - может быть, вы хотели добавить комментарий к исходному ответу?
Спасибо - не думал, что это будет просто или красиво. :)