Как подключиться к экземплярам Java, работающим на EC2, используя JMX
у нас возникли проблемы с подключением к нашим Java-приложениям, работающим в кластере EC2 Amazon. Мы определенно разрешили как "порт JMX" (который обычно является портом реестра RMI) и порт сервера (который выполняет большую часть работы) для группы безопасности для рассматриваемых экземпляров. Jconsole подключается, но, похоже, висит и никогда не показывает никакой информации.
мы запускаем нашу java с чем-то вроде следующего:
java -server -jar foo.jar other parameters here > java.log 2>&1
мы попробовал:
- Telnets к портам подключиться но информация не отображается.
- мы можем работать
jconsole
на самом экземпляре, использующем remote-X11 через ssh, и он подключается и показывает информацию. Итак, JRE и экспортировать его локально. - открытие всех портов в группе безопасности. Weeee.
- используя
tcpdump
чтобы убедиться, что трафик не идет через другие порты. - имитация локально. Мы всегда можно подключиться к нашим локальным JREs или тем, кто работает в другом месте в нашей сети, используя те же параметры приложения.
java -version
выходы:
OpenJDK Runtime Environment (IcedTea6 1.11.5) (amazon-53.1.11.5.47.amzn1-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
в стороне, мы используем мой простой JMX пакет, который позволяет ставить и реестр RMI и порты сервера, которые обычно полу-случайным образом выбираются реестром RMI. Вы также можете эту силу, что и JMX Ури:
service:jmx:rmi://localhost:" + serverPort + "/jndi/rmi://:" + registryPort + "/jmxrmi"
в наши дни мы используем один и тот же порт как для сервера, так и для реестра. В прошлом мы использовали X
как реестр-порт и X+1
для сервера-порт, чтобы сделать правила группы безопасности легко. Вы подключаетесь к порту реестра в jconsole
или любой клиент JMX, который вы используете.
4 ответов
у нас возникли проблемы с подключением к нашим Java-приложениям, работающим в кластере EC2 Amazon.
оказывается, проблема заключалась в сочетании двух отсутствующих настроек. Первый заставляет JRE предпочесть ipv4 и не В6. Это было необходимо (я думаю), так как мы пытаемся подключиться к нему через V4 адресу:
-Djava.net.preferIPv4Stack=true
реальным блокатором был тот факт, что JMX работает, сначала связавшись с портом RMI, который отвечает с хоста и порт для подключения клиента JMX. Без дополнительных настроек он будет использовать локальный IP-адрес окна, который является 10.X.X.X
виртуальный адрес, к которому удаленный клиент не может маршрутизировать. Нам нужно добавить следующий параметр, который является внешний имя хоста или IP сервера -- в этом случае это эластичное имя хоста сервера.
-Djava.rmi.server.hostname=ec2-107-X-X-X.compute-1.amazonaws.com
трюк, если вы пытаетесь автоматизировать свои экземпляры EC2 (и почему, черт возьми, вы нет), как найти этот адрес во время выполнения. Для этого вам нужно поместить что-то вроде следующего в наш скрипт загрузки приложения:
# get our _external_ hostname
RMI_HOST=`wget -q -O - http://169.254.169.254/latest/meta-data/public-hostname`
...
java -server \
-Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=$RMI_HOST \
-jar foo.jar other parameters here > java.log 2>&1
таинственная 169.254.169.254
IP в wget
команда выше предоставляет информацию, которую экземпляр EC2 может запросить о себе. Я разочарован, что это не не включить теги, которые доступны только в подлинности вызова.
Я изначально использовал внешний ipv4-адрес, но он выглядит так при запуске JDK пытается установить соединение с портом сервера. Если он использует внешний IP-адрес, это замедляет время загрузки приложения до истечения времени ожидания. Имя общедоступного хоста локально разрешается в адрес 10-net и в общедоступный ipv4 извне. Таким образом, приложение теперь запускается быстро, и клиенты JMX все еще работают. Ура!
надеюсь, это поможет кому-то еще. Сегодня я потратил 3 часа.
чтобы заставить ваш сервер JMX запустить сервер и реестр RMI на назначенных портах, чтобы вы могли блокировать их в группах безопасности EC2, см. Этот ответ:
Edit:
у нас просто возникла эта проблема. Кажется, что Java JMX-код выполняет некоторые поиски имени хоста на имени хоста коробки и использует их, чтобы попытаться подключиться и проверить JMX соединение.
проблема, по-видимому, является требованием, чтобы локальное имя хоста коробки должно разрешаться локальному ip-адресу коробки. Например, если ваш /etc/sysconfig/network
и HOSTNAME=server1.foobar.com
тогда, если вы делаете поиск в DNS server1.foobar.com
, вы должны добраться до виртуального адреса 10-NET. Мы создавали свои собственные /etc/hosts
файл и имя хоста локального хоста отсутствовали в файле. Это заставило наши приложения либо приостановить запуск, либо не запускать при запуске все.
и наконец
один из способов упростить создание JMX-использовать my пакет SimpleJMX.
за второй ответ почему соединение JMX с Amazon EC2 не удается?, трудность здесь в том, что по умолчанию порт RMI выбран случайным образом, и клиентам нужен доступ как к портам JMX, так и к портам RMI. Если вы используете jdk7u4 или более позднюю версию, порт RMI можно указать с помощью свойства app. Запуск моего сервера со следующими настройками JMX работал для меня:
без проверки подлинности:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9998
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=<public EC2 hostname>
проверка подлинности:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9998
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password
-Djava.rmi.server.hostname=<public EC2 hostname>
I также открыты порты 9998-9999 в группе безопасности EC2 для моего экземпляра.
немного другой подход, используя SSH-туннели
- (на удаленном компьютере) передайте следующие флаги JVM
-Dcom.sun.management.jmxremote.port=1099
-Djava.net.preferIPv4Stack=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=127.0.0.1
- (на удаленной машине) проверьте, какие порты java начала использовать
netstat -tulpn | grep java
tcp 0 0 0.0.0.0:37484 0.0.0.0:* LISTEN 2904/java
tcp 0 0 0.0.0.0:1099 0.0.0.0:* LISTEN 2904/java
tcp 0 0 0.0.0.0:45828 0.0.0.0:* LISTEN 2904/java
- (на локальной машине) сделайте ssh-туннели для всех портов
ssh -N -L 1099:127.0.0.1:1099 ubuntu@<ec2_ip>
ssh -N -L 37484:127.0.0.1:37484 ubuntu@<ec2_ip>
ssh -N -L 45828:127.0.0.1:45828 ubuntu@<ec2_ip>
- (на локальном компьютере) подключение от Java Mission Control до "localhost: 1099"
ответ, данный Греем, работал для меня, однако я нахожу, что мне нужно открыть TCP-порты 0 до 65535 или я не вхожу. Я!--1-->думаю что вы можете подключиться к основному порту JMX, а затем получить другой назначенный. Я получил это от этот блог это всегда хорошо работало для меня.