mirror of
https://github.com/Dannecron/spring-boot-demo.git
synced 2025-12-26 00:32:34 +03:00
add entrypoint to dockerfile and doc
fix resource usage
This commit is contained in:
278
doc/entrypoint.md
Normal file
278
doc/entrypoint.md
Normal file
@@ -0,0 +1,278 @@
|
||||
# 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` и соответственно лимит памяти контейнера.
|
||||
Reference in New Issue
Block a user