Files
spring-boot-demo/doc/entrypoint.md
Savosin Denis e6db3360c2 add entrypoint to dockerfile and doc
fix resource usage
2025-11-06 15:47:56 +07:00

14 KiB
Raw Blame History

Entrypoint: Запуск JAR-файла и конфигурация JVM

LLM-generated документация.

Оглавление

Обзор

Скрипт 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
  • Дефолтные значения всех переменных

Расчет:

  1. Складские ресурсы:

    STOCK_SIZE_MB = (100/2) + 10 + 120 = 180 MB
    
  2. Доступная память для JVM:

    LIMITED_MAXRAM_JAVA_SIZE_MB = 512 - 180 = 332 MB
    
  3. Non-heap память:

    NON_HEAP_SIZE_MB = 64 + 80 + 10 + 16 = 170 MB
    
  4. Память для Heap + GC:

    HEAP_GC_SIZE_MB = 332 - 170 = 162 MB
    
  5. GC overhead:

    OVERHEAD_GC_SIZE_MB = (162 * 5) / 100 = 8 MB
    
  6. Финальный размер Heap:

    HEAP_SIZE_MB = 162 - 8 = 154 MB
    
  7. Процент 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 Комфортный

Рекомендации по настройке:

  1. Для высоко нагруженных приложений - увеличьте TOMCAT_THREADS_MAX
  2. Для БД-интенсивных приложений - увеличьте HIKARI_DB_MAXIMUM_POOL_SIZE
  3. Для приложений с большим количеством классов - увеличьте MAX_METASPACE_SIZE_MB
  4. При частых 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 и соответственно лимит памяти контейнера.