Как вы определяете размер кучи / не кучи для ваших микросервисов Java с помощью Docker? - PullRequest
0 голосов
/ 15 февраля 2019

Мы используем микросервисы Java в AWS ECS.Поэтому для Docker мы указываем жесткий предел кучи Java с помощью -Xmx.Это очень сложная часть, чтобы определить, сколько памяти мы можем оставить для кучи и сколько нам нужно для не-кучи памяти (метапространство, стек, JIT-кеш и т. Д.). В настоящее время мы проводим стресс-тест, чтобы определить, когда у нас есть Docker OOMKiller .Например, для задачи AWS 2 ГБ (докер), максимум, который мы можем установить для кучи -Xmx1400m (с -Xmx1450m у нас недостаточно памяти для вещей, не относящихся к куче (выход Code137)) На самом деле, Java 10+ имеет "-XX: MaxRAMPercentage«но нам все еще нужно знать этот процент.

Как определить размер кучи / размера без кучи для ваших микросервисов Java? Или стресс-тест является единственным решением?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Начиная с Java 8u131, есть возможность установить ограничения JVM на основе ограничений памяти контейнера .Поэтому, если вы запустите что-то вроде:

docker run \
  -m 2g \     # set a container memory limit
  openjdk:8 \
  java \
    -XX:+UnlockExperimentalVMOptions \
    -XX:+UseCGroupMemoryLimitForHeap \
    com.example.Classname

, JVM установит ограничение кучи так, чтобы оно соответствовало пределу памяти контейнера в 2 ГБ, выполнив для вас -Xmx.В принципе, это должно устроить так, что вы никогда не достигнете предела памяти контейнера, а получите сначала Java OutOfMemoryError.

В этом посте есть еще пара примеров на эту тему, итакже предлагает -XX:MaxRamFraction=1 разрешить использование «всей памяти», где вы ограничены этим с помощью опции docker run -m.

На практике вы, вероятно, установите $JAVA_OPTS в Dockerfile, например

FROM openjdk:8
COPY app.jar /
ENV JAVA_OPTS=-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRamFraction=1
CMD ["java", "-jar", "/app.jar"]

и затем запустите его как

docker run -d -p ... -m 2g myimage

В среде Kubernetes объявленный предел памяти в ограничениях ресурсов модуля играет ту же роль.

Как подсказывает @KarolDowbecki в своихответ, вам нужно сделать некоторые профилирование и мониторинг, чтобы на самом деле выбрать правильный номер для этого.Запуск приложения локально и мониторинг статистики RSS (размер резидентного набора) в ps или top должны дать вам разумный базовый уровень.

0 голосов
/ 15 февраля 2019

Запуск эталонного теста, вероятно, является правильным подходом, однако на практике выполнение этого для каждого имеющегося у вас микросервиса может оказаться очень дорогостоящим.С одной стороны, без эталона невозможно угадать, как микросервис ведет себя под нагрузкой, например, из-за уменьшения памяти увеличится время обработки запроса из-за GC.С другой стороны, ОЗУ относительно дешево по сравнению со временем разработчика, и написание тестов для распределенных систем откровенно сложно.

Я не верю, что нет формулы для расчета этого на бумаге.Ответ будет зависеть от каждой реализации и использования микросервиса.Это должен быть постоянный цикл тестирования и мониторинга, если проблема обнаружена, то параметры памяти должны быть скорректированы для ее устранения.

Как правило, инвестиции в мониторинг должны приносить лучшую отдачу, чем написание набора тестов.

...