В чем секрет микроконтейнеров на Java™
Санкт-Петербург, 16 апреля 2021 г.
В этой статье мы решили приоткрыть тайну создания миниатюрных образов Axiom JDK, незаменимых в облачных окружениях. Здесь представлены два основных метода уменьшения образов, а также инструменты для сокращения размера контейнеров в рамках вашего проекта.
Введение
В любой компании знают, насколько важна скорость. Это касается и вашего ПО: чем меньше времени занимает его перенос и развертывание, тем больше данных вы сможете обработать и тем выше будет прибыль. Поэтому крошечные образы в Docker-контейнерах и стали так популярны. Их малый вес и производительность экономят драгоценное время при разработке, реализации и производстве, увеличивая тем самым ваш доход.
Классический контейнер для разработки приложения включает несколько слоев: собственно приложение, фреймворк, библиотеки, различные пакеты. Но если говорить об оптимизации (например, в контексте микросервисной архитектуры) в Linux-контейнере легче выделить только два главных компонента: базовый образ и JDK, которые всегда влияют на объем занимаемой памяти. Ниже мы расскажем об изменениях, которые позволили нам максимально уменьшить контейнеры.
Как сократить размер контейнера
1. Использовать образ другой ОС
Первый вариант довольно прост. Вместо тяжелой полной версии CentOS скачайте тонкий клиент. Если этого недостаточно, смените операционную систему на Debian. Оптимальным выбором будет Alpine musl. Благодаря легковесности базового образа Axiom JDK считает Alpine Linux самой благоприятной ОС для разработки.
Взгляните на графики. Мы сравнили размеры контейнеров Axiom JDK (версии 11.0.10 + ранние сборки 11.0.10) с тремя дистрибутивами Linux.
Дистрибутивы Axiom EA, выпущенные в январе, меньше на 3–6 Мб, что составляет 14,7 % веса образа модуля java.base на Alpine musl. В среднем показатели улучшились на 7,6 %.
Если компиляция приложений внутри Docker-образа не требуется, можно использовать как JRE, так и java.base. Аналогичная положительная динамика отмечается и для Axiom JRE EA: в среднем пакеты уменьшились на 16 %.
Axiom JDK предлагает три варианта Axiom JDK:
- Full, укомплектованный сборкой платформы AxiomFX (на базе OpenJFX), минимальной виртуальной машиной MinimalVM и встроенными модулями реализации API ввода-вывода (DIO) — идеальное решение для масштабной разработки;
- Standard оптимально подходит для большинства десктопов/серверов;
- легковесный Lite — прекрасный вариант для облачных экземпляров, позволяющий минимизировать ресурсы.
При этом Axiom Lite от Axiom JDK не является урезанной версией, ограничивающей возможности проекта. Это полноценная среда исполнения, которая прошла проверку с помощью пакета соответствия OpenJDK TCK. Она полностью совместима со спецификациями Java SE. Графики наглядно демонстрируют, что этот вариант среды наиболее предпочтителен для микроконтейнеров, так как обеспечивает высокую производительность и максимальную скорость.
Влияет ли малый размер на функциональность? Нисколько. Дистрибутивы Lite все так же совместимы со спецификацией Java SE и поддерживают полный спектр функций JVM: JIT-компиляторы (C1, C2, Graal JIT Compiler), сборщики мусора (Serial, Parallel, CMS, G1, Shenandoah, ZGC), а также функции обслуживания (если применимо).
Каждый релиз подвергается тщательному контролю качества. Он включает основные отраслевые тесты для оценки дистрибутивов, а также измерение фактической производительности с помощью наборов библиотек Java Microbenchmark Harness. Мы стремились показать отсутствие различий в функциональности, а также подчеркнуть одинаковую скорость запуска дистрибутивов вариантов поставки Axiom Lite и Standard. Результаты производительности для версии 11.0.10 EA выглядят следующим образом.
SpecJBB 2015
- JDK 11.0.10
- 4 теста, представлены средние значения
- Cascade Lake Intel CPU, 48 ядер, 128 Gb RAM
- Настройки бэкенда:
-server -XX:+PrintFlagsFinal -XX:+UseParallelGC -Xnoclassgc -XX:-UseAdaptiveSizePolicy -XX:+AlwaysPreTouch -XX:+UseBiasedLocking -XX:-UsePerfData -XX:-UseNUMA -XX:-UseNUMAInterleaving -XX:InlineSmallCode=20k -XX:CompileThreshold=1000 -XX:-SegmentedCodeCache -XX:MaxInlineLevel=15 -XX:ParallelGCThreads=56 -Xmx102400m -Xms102400m -Xmn76800m -XX:SurvivorRatio=130 -XX:TargetSurvivorRatio=66 -XX:MaxTenuringThreshold=15
- Системные настройки: Page Size = 512 Mb
DaCapo Benchmark Suite
- JDK 11.0.10
- 9.12-bach-MR1 benchmark revision
- 20 тестов, из которых вычисляется среднеквадратичное отклонение.
- Skylake Intel CPU, 4 ядра
Помимо вспомогательных тестов мы провели расчет среднего геометрического значения, которое также представлено на графике ниже.
Как видно по графикам, статистически значимые различия со стандартной версией отсутствуют. Кроме того, мы провели целый ряд других тестов производительности. При этом ни один показатель облегченной версии не был хуже аналогичных показателей стандартной версии с точки зрения статистической значимости. На основании проведенных тестов можно сделать вывод, что исполняемые файлы облегченной версии Axiom Lite EA 11.0.10 не уступают стандартной по производительности и скорости запуска.
Скачайте последние версии пакетов или ознакомьтесь с полным ассортиментом продукции Axiom JDK.
2. Минимизируйте JDK
Как вариант, можно исключить ненужные модули из рантайма с помощью jdeps
и jlink.
Мы подготовили для вас наглядный пример.
Вы можете проделать указанные ниже шаги, взяв небольшое приложение из этого файла в качестве иллюстрации.
Сначала запустите инструмент анализа зависимостей Java (JDeps). Он обрабатывает байт-код, то есть файлы классов или JAR, которые их содержат, а также анализирует статически объявленные зависимости между классами. Здесь мы представим альтернативный метод его использования. JDeps содержит все сведения о модулях системы. Инструмент формирует список JDK-модулей, необходимых для работы приложения на Java™. Только они и войдут в итоге в нативный образ.
jdeps duke_ascii.jar
duke_ascii.jar -> java.base
bellsoft.duke -> java.io java.base
bellsoft.duke -> java.lang java.base
После анализа кода с помощью jdeps
становится ясно, что он использует только java.base.
В случае крупного приложения с большим количеством зависимостей и библиотек мы бы использовали jlink
для уменьшения рантайма. К счастью, у Axiom JDK уже есть свой образ с java.base.
Вы можете скачать подготовленную сборку образа с этим приложением на Docker Hub.
Запустите приложение: docker run --rm bellsoft/axiom-openjdk-demos-asciiduke.
&&&
&&&&&&&
&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&
&&&&% %%%%%%&&&&
&&&&%%%%%%%%%%%%%&&&&
&& &&%%%%%%%%%%%%&& &&&
&&& &&%%%%%%%&&& &&&&&
&& && & &&
& & & &&
&&&&& &&&&&
&&&& &&&&
&&&&& &&&&&&
& &&&&&&&&& & &
&& &&& && &&
Для большинства приложений командной строки достаточно модуля java.base. В итоге, размер образа, созданного с помощью Axiom JDK Lite на базе Alpine Linux musl составит всего 40,4 Мб, включая само приложение!
После упаковки и запуска, с нашим крошечным образом вы получите самый маленький Docker-контейнер.
Заключение
Многие разработчики создают файлы образов и контейнеры самостоятельно, потому что их не устраивают доступные на рынке варианты. Наши подробные инструкции и легковесные образы Axiom JRE/JDK позволят вам сосредоточиться непосредственно на своем проекте, не отвлекаясь на эту проблему.
Axiom JDK будет и дальше добиваться уменьшения образов. Дистрибутивы Axiom Early Access 11.0.10 демонстрируют снижение размеров на 8–16 % по сравнению с обычными. Если вы хотите оперативно получать информацию о новых продвинутых функциях, свяжитесь с инженерами Axiom JDK. Наши эксперты, имеющие более чем 15-летний опыт работы с Java™, проведут для вас бесплатную консультацию. Узнайте, как получить ранний доступ к продуктам, способным коренным образом изменить и оптимизировать проекты любого масштаба: на десктопах, серверах и в облачных средах.