Как отслеживать использование памяти Java-приложениями в Docker
Я запускаю веб-приложение Java на Tomcat в контейнере Docker.
Есть ли способ контролировать использование памяти Java-приложения? Я пытаюсь использовать jconsole
с идентификатором процесса докера, но он говорит мне Invalidate process id
Я также включаю JMX в tomcat, но не знаю, как с ним связываться. я могу использовать visualvm
из моего локального, чтобы связать хост-машину, но не могу найти способ связать с докером внутри хоста.
Есть ли хороший способ добиться этого?
Спасибо
6 ответов
Чтобы подключиться к процессу Java, запущенному в Docker-контейнере, запущенном в boot2docker
с visualvm
Вы можете попробовать следующее:
Запустите процесс Java, используя следующие параметры:
java -Dcom.sun.management.jmxremote.port=<port> \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.rmi.port=<port> \
-Djava.rmi.server.hostname=<boot2docker_ip> \
<Main>
Вам нужно запустить свое изображение с --expose <port> -p <port>:<port>
,
Затем "Добавить соединение JMX" в visualvm
с <boot2docker_ip>:<port>
,
Это не должно сильно отличаться без boot2docker
,
Для мониторинга докер-контейнеров я рекомендую Google cAdvisor
проект. Таким образом, у вас есть общее решение для мониторинга док-контейнеров. Просто запустите ваше приложение, что бы это ни было, в контейнере Docker, и проверьте такие вещи, как процессор и использование памяти. Здесь у вас есть http API, а также веб-интерфейс.
Чтобы отслеживать его использование, вам нужно получить его реальный идентификатор процесса. Если вы запускаете tomcat прямо в контейнере, то это должно быть:
DOCKER_ROOT_PROC=`(docker inspect -f "{{ .State.Pid }}" my_container)`
Если вы используете что-то вроде базового образа Phusion, то ваш Java-процесс будет дочерним для этого процесса. Чтобы увидеть иерархию используйте:
pstree $DOCKER_ROOT_PROC
Если у вас есть это, вы можете написать свой сценарий, используя
ps -o pid,cmd --no-headers --ppid $DOCKER_ROOT_PROC
В вашем скрипте рекурсивно найти процесс Java, который вы хотите отслеживать (конечно, с некоторой фильтрацией регулярных выражений). Затем, наконец, вы можете использовать это, чтобы получить использование памяти вашего Java-приложения в килобайтах:
ps -o vsz -p $JAVAPROCESS
Я не знаю, можно ли это использовать с jconsole, но это способ мониторинга использования памяти.
Упомянутый выше cAdvisor не поможет контролировать Tomcat, работающий внутри контейнера. Возможно, вы захотите взглянуть на Docker-контейнер SPM Client, который делает именно это! В нем есть агенты для мониторинга ряда различных приложений, работающих в Docker - Elasticsearch, Solr, Tomcat, MySQL и т. Д.: https://github.com/sematext/docker-spm-client
Для мониторинга использования памяти вашего приложения в Docker вы также можете запустить ejstatd внутри вашего контейнера Docker (вызов mvn -Djava.rmi.server.hostname=$HOST_HOSTNAME exec:java -Dexec.args="-pr 2222 -ph 2223 -pv 2224" &
из папки ejstatd перед запуском процесса основного контейнера), предоставив эти 3 порта хосту Docker с помощью docker run -e HOST_HOSTNAME=$HOSTNAME -p 2222:2222 -p 2223:2223 -p 2224:2224 myimage
,
Затем вы сможете подключиться к этому специальному демону jstatd, используя, например, JVisualVM, добавив "Удаленный хост", указав в качестве имени хоста свое имя хоста Docker, и добавив "Настраиваемые соединения jstatd" (в "Расширенных настройках"), установив "2222" в "Порт".
Отказ от ответственности: я являюсь автором этого инструмента с открытым исходным кодом.
Я попробовал ответ Пьера ( также ответил здесь), но никак не мог.
В конце я смог подключиться через SSH туннель.