Как подключиться к экземплярам 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, см. Этот ответ:

как закрыть rmiregistry, работающую на определенном порту?

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-туннели

  1. (на удаленном компьютере) передайте следующие флаги 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

  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

  1. (на локальной машине) сделайте 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>

  1. (на локальном компьютере) подключение от Java Mission Control до "localhost: 1099"

ответ, данный Греем, работал для меня, однако я нахожу, что мне нужно открыть TCP-порты 0 до 65535 или я не вхожу. Я!--1-->думаю что вы можете подключиться к основному порту JMX, а затем получить другой назначенный. Я получил это от этот блог это всегда хорошо работало для меня.