14 KiB
Entrypoint: Запуск JAR-файла и конфигурация JVM
LLM-generated документация.
Оглавление
- Обзор
- Алгоритм работы
- JVM флаги и их назначение
- Экспортируемые переменные
- Пример расчета
- Мониторинг и отладка
- Troubleshooting
Обзор
Скрипт entrypoint.sh выполняет интеллектуальную настройку JVM на основе ограничений памяти контейнера. Он автоматически вычисляет оптимальные размеры heap, non-heap областей и других параметров для обеспечения стабильной работы Spring Boot приложения.
Параметры запуска
-v- включает verbose режим с выводом отладочной информации о расчетах памятиJAR_FILE_NAME- имя JAR-файла для запуска (позиционный аргумент)
Пример использования:
./entrypoint.sh -v app.jar # С отладочной информацией
./entrypoint.sh app.jar # Без отладочной информации
Алгоритм работы
1. Определение ограничений памяти контейнера
# Проверка версии cgroups и получение лимита памяти
if [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then
# Cgroups v1
LIMITED_RAM_CONTAINER_CGROUP_SIZE_BYTES=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
elif [ -f /sys/fs/cgroup/memory.max ]; then
# Cgroups v2
LIMITED_RAM_CONTAINER_CGROUP_SIZE_BYTES=$(cat /sys/fs/cgroup/memory.max)
else
# Ошибка: нет доступа к информации о памяти
exit 1
fi
Результат: Получение лимита памяти контейнера в байтах.
2. Конфигурация компонентов приложения
Переменные окружения со значениями по умолчанию:
| Переменная | Значение по умолчанию | Описание |
|---|---|---|
TOMCAT_THREADS_MAX |
100 | Максимальное количество потоков Tomcat |
TOMCAT_THREADS_MIN |
= TOMCAT_THREADS_MAX | Минимальное количество потоков Tomcat |
HIKARI_DB_MAXIMUM_POOL_SIZE |
10 | Максимальный размер пула соединений БД |
HIKARI_DB_MINIMUM_IDLE_SIZE |
= HIKARI_DB_MAXIMUM_POOL_SIZE | Минимальное количество idle соединений |
JVM_NATIVE_MB |
120 | Резерв памяти для native кода JVM |
3. Расчет "складских" ресурсов
STOCK_SIZE_MB = (TOMCAT_THREADS_MAX / 2) + HIKARI_DB_MAXIMUM_POOL_SIZE + JVM_NATIVE_MB
Логика расчета:
- Tomcat потоки: каждый поток потребляет ~0.5 MB памяти
- Пул соединений БД: каждое соединение ~1 MB
- Native память JVM: фиксированный резерв для JNI, сжатия, etc.
Пример: При дефолтных значениях: (100/2) + 10 + 120 = 180 MB
4. Расчет доступной памяти для JVM
LIMITED_MAXRAM_JAVA_SIZE_MB = LIMITED_RAM_CONTAINER_CGROUP_SIZE_MB - STOCK_SIZE_MB
Назначение: Память, которую JVM может использовать без риска превышения лимитов контейнера.
5. Настройка Non-Heap областей JVM
Конфигурация областей памяти:
| Область | Переменная | Значение по умолчанию | Назначение |
|---|---|---|---|
| Code Cache | RESERVED_CODE_CACHE_SIZE_MB |
64 MB | Компилированный JIT код |
| Metaspace | MAX_METASPACE_SIZE_MB |
80 MB | Метаданные классов |
| Direct Buffers | DIRECT_BYTES_BUFFERS_MB |
10 MB | NIO буферы |
| Compressed Class Space | COMPRESSED_CLASS_SPACE_MB |
16 MB | Сжатые указатели на классы |
NON_HEAP_SIZE_MB = RESERVED_CODE_CACHE_SIZE_MB + MAX_METASPACE_SIZE_MB +
DIRECT_BYTES_BUFFERS_MB + COMPRESSED_CLASS_SPACE_MB
6. Расчет Heap памяти
Этап 1: Память доступная для Heap + GC
HEAP_GC_SIZE_MB = LIMITED_MAXRAM_JAVA_SIZE_MB - NON_HEAP_SIZE_MB
Этап 2: Резерв для GC overhead
OVERHEAD_GC_SIZE_PERCENT = 5 # По умолчанию 5%
OVERHEAD_GC_SIZE_MB = (HEAP_GC_SIZE_MB * OVERHEAD_GC_SIZE_PERCENT) / 100
Этап 3: Финальный размер Heap
HEAP_SIZE_MB = HEAP_GC_SIZE_MB - OVERHEAD_GC_SIZE_MB
Этап 4: Процент от MaxRAM для JVM
MAX_RAM_PERCENTAGE = (HEAP_SIZE_MB * 100) / LIMITED_MAXRAM_JAVA_SIZE_MB
JVM флаги и их назначение
Контейнерная поддержка
-XX:+UseContainerSupport- Включает автоопределение ресурсов контейнера-XX:MaxRAM="${LIMITED_MAXRAM_JAVA_SIZE_MB}m"- Максимальная память для JVM-XX:MaxRAMPercentage="$MAX_RAM_PERCENTAGE"- Процент MaxRAM для heap
Управление памятью
-XX:+ExitOnOutOfMemoryError- Принудительное завершение при OOM-XX:MaxMetaspaceSize="${MAX_METASPACE_SIZE_MB}m"- Лимит Metaspace
Оптимизация производительности
-XX:+SegmentedCodeCache- Сегментированный code cache для лучшей производительности-XX:ReservedCodeCacheSize="${RESERVED_CODE_CACHE_SIZE_MB}m"- Размер code cache
Дополнительные опции
$JAVA_OPTS_OVERRIDE- Переменная для переопределения опций
Экспортируемые переменные
Скрипт экспортирует рассчитанные значения для использования приложением:
export TOMCAT_THREADS_MAX=$TOMCAT_THREADS_MAX
export TOMCAT_THREADS_MIN=$TOMCAT_THREADS_MIN
export HIKARI_DB_MAXIMUM_POOL_SIZE=$HIKARI_DB_MAXIMUM_POOL_SIZE
export HIKARI_DB_MINIMUM_IDLE_SIZE=$HIKARI_DB_MINIMUM_IDLE_SIZE
Пример расчета
Дано:
- Лимит контейнера: 512 MB
- Дефолтные значения всех переменных
Расчет:
-
Складские ресурсы:
STOCK_SIZE_MB = (100/2) + 10 + 120 = 180 MB -
Доступная память для JVM:
LIMITED_MAXRAM_JAVA_SIZE_MB = 512 - 180 = 332 MB -
Non-heap память:
NON_HEAP_SIZE_MB = 64 + 80 + 10 + 16 = 170 MB -
Память для Heap + GC:
HEAP_GC_SIZE_MB = 332 - 170 = 162 MB -
GC overhead:
OVERHEAD_GC_SIZE_MB = (162 * 5) / 100 = 8 MB -
Финальный размер Heap:
HEAP_SIZE_MB = 162 - 8 = 154 MB -
Процент RAM для heap:
MAX_RAM_PERCENTAGE = (154 * 100) / 332 = 46%
Результирующая команда Java:
exec java \
-XX:+UseContainerSupport \
-XX:+ExitOnOutOfMemoryError \
-XX:MaxRAM="332m" \
-XX:MaxRAMPercentage="46" \
-XX:+SegmentedCodeCache \
-XX:ReservedCodeCacheSize="64m" \
-XX:MaxMetaspaceSize="80m" \
-jar /app/app.jar
Мониторинг и отладка
Verbose режим (-v)
При запуске с флагом -v скрипт выводит отладочную информацию:
# Версия cgroups
Cgroups v2 are used
# Расчеты памяти
LIMITED_MAXRAM_JAVA_SIZE_MB=332
HEAP_SIZE_MB=154
MAX_RAM_PERCENTAGE=46
Без флага -v - никаких отладочных сообщений не выводится, только стандартные логи приложения.
Рекомендуемые размеры контейнеров
| Размер контейнера | Heap | Статус |
|---|---|---|
| ≤ 352 MB | ❌ Отрицательный | Не работает |
| 353 MB | 🔴 3 MB | Критический минимум |
| 400 MB | 🟡 47 MB | Базовый |
| 512 MB | 🟢 154 MB | Рекомендуемый |
| 768 MB | 🟢 380 MB | Комфортный |
Рекомендации по настройке:
- Для высоко нагруженных приложений - увеличьте
TOMCAT_THREADS_MAX - Для БД-интенсивных приложений - увеличьте
HIKARI_DB_MAXIMUM_POOL_SIZE - Для приложений с большим количеством классов - увеличьте
MAX_METASPACE_SIZE_MB - При частых OOM - уменьшите
OVERHEAD_GC_SIZE_PERCENTили увеличьте память контейнера
Troubleshooting
Проблема: Приложение падает с OOM
Решение: Проверьте соотношение heap/non-heap памяти, возможно нужно увеличить лимит контейнера.
Проблема: Медленная работа GC
Решение: Увеличьте OVERHEAD_GC_SIZE_PERCENT или используйте альтернативный GC через JAVA_OPTS_OVERRIDE.
Проблема: Много database connections timeout
Решение: Увеличьте HIKARI_DB_MAXIMUM_POOL_SIZE и соответственно лимит памяти контейнера.