# Entrypoint: Запуск JAR-файла и конфигурация JVM _LLM-generated документация._ ## Оглавление - [Обзор](#обзор) - [Параметры запуска](#параметры-запуска) - [Алгоритм работы](#алгоритм-работы) - [1. Определение ограничений памяти контейнера](#1-определение-ограничений-памяти-контейнера) - [2. Конфигурация компонентов приложения](#2-конфигурация-компонентов-приложения) - [Переменные окружения со значениями по умолчанию:](#переменные-окружения-со-значениями-по-умолчанию) - [3. Расчет "складских" ресурсов](#3-расчет-складских-ресурсов) - [4. Расчет доступной памяти для JVM](#4-расчет-доступной-памяти-для-jvm) - [5. Настройка Non-Heap областей JVM](#5-настройка-non-heap-областей-jvm) - [Конфигурация областей памяти:](#конфигурация-областей-памяти) - [6. Расчет Heap памяти](#6-расчет-heap-памяти) - [Этап 1: Память доступная для Heap + GC](#этап-1-память-доступная-для-heap--gc) - [Этап 2: Резерв для GC overhead](#этап-2-резерв-для-gc-overhead) - [Этап 3: Финальный размер Heap](#этап-3-финальный-размер-heap) - [Этап 4: Процент от MaxRAM для JVM](#этап-4-процент-от-maxram-для-jvm) - [JVM флаги и их назначение](#jvm-флаги-и-их-назначение) - [Контейнерная поддержка](#контейнерная-поддержка) - [Управление памятью](#управление-памятью) - [Оптимизация производительности](#оптимизация-производительности) - [Дополнительные опции](#дополнительные-опции) - [Экспортируемые переменные](#экспортируемые-переменные) - [Пример расчета](#пример-расчета) - [Дано:](#дано) - [Расчет:](#расчет) - [Результирующая команда Java:](#результирующая-команда-java) - [Мониторинг и отладка](#мониторинг-и-отладка) - [Verbose режим (`-v`)](#verbose-режим--v) - [Рекомендуемые размеры контейнеров](#рекомендуемые-размеры-контейнеров) - [Рекомендации по настройке:](#рекомендации-по-настройке) - [Troubleshooting](#troubleshooting) - [Проблема: Приложение падает с OOM](#проблема-приложение-падает-с-oom) - [Проблема: Медленная работа GC](#проблема-медленная-работа-gc) - [Проблема: Много database connections timeout](#проблема-много-database-connections-timeout) ## Обзор Скрипт `entrypoint.sh` выполняет интеллектуальную настройку JVM на основе ограничений памяти контейнера. Он автоматически вычисляет оптимальные размеры heap, non-heap областей и других параметров для обеспечения стабильной работы Spring Boot приложения. ### Параметры запуска - **`-v`** - включает verbose режим с выводом отладочной информации о расчетах памяти - **`JAR_FILE_NAME`** - имя JAR-файла для запуска (позиционный аргумент) **Пример использования:** ```bash ./entrypoint.sh -v app.jar # С отладочной информацией ./entrypoint.sh app.jar # Без отладочной информации ``` ## Алгоритм работы ### 1. Определение ограничений памяти контейнера ```bash # Проверка версии 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. Расчет "складских" ресурсов ```bash 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 ```bash 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 | Сжатые указатели на классы | ```bash 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 ```bash HEAP_GC_SIZE_MB = LIMITED_MAXRAM_JAVA_SIZE_MB - NON_HEAP_SIZE_MB ``` #### Этап 2: Резерв для GC overhead ```bash OVERHEAD_GC_SIZE_PERCENT = 5 # По умолчанию 5% OVERHEAD_GC_SIZE_MB = (HEAP_GC_SIZE_MB * OVERHEAD_GC_SIZE_PERCENT) / 100 ``` #### Этап 3: Финальный размер Heap ```bash HEAP_SIZE_MB = HEAP_GC_SIZE_MB - OVERHEAD_GC_SIZE_MB ``` #### Этап 4: Процент от MaxRAM для JVM ```bash 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`** - Переменная для переопределения опций ## Экспортируемые переменные Скрипт экспортирует рассчитанные значения для использования приложением: ```bash 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: ```bash 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` скрипт выводит отладочную информацию: ```bash # Версия 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` и соответственно лимит памяти контейнера.