Fix for jvm Dockerfile.jvm

This commit is contained in:
dakocha3
2026-09-21 18:59:00 +03:00
parent 13f5a93533
commit c7e5b02362
2 changed files with 54 additions and 3 deletions
+51 -2
View File
@@ -213,8 +213,10 @@ docker build -f src/main/docker/Dockerfile.native -t pd-guard .
docker run --rm -p 8080:8080 -v "$PWD/config:/work/config:ro" pd-guard
```
Запасной вариант на JVM — `src/main/docker/Dockerfile.jvm`; прогрев там обязателен,
иначе первые секунды нагрузки идут по интерпретируемому коду.
Вариант на JVM — `src/main/docker/Dockerfile.jvm`. Настройку сборщика мусора и
размер кучи задаёт базовый образ: добавлять `-XX:+UseZGC` поверх нельзя, образ уже
включает ParallelGC и JVM не стартует с двумя сборщиками. Сравнение с native по
скорости и памяти — в разделе о потреблении ресурсов.
Проверка:
@@ -282,6 +284,53 @@ Native-образ в Docker Desktop, Apple M-серия. Один узел, со
| 1000 | 1,57 мс | 0 | 100 % |
| 2000 | 0,98 мс | 0 | 100 % |
## Потребление ресурсов
Замер снят с контейнера во время нагрузки; генератор работал на той же машине
(8 ядер, Docker-ВМ 7,7 ГБ), поэтому часть процессора съедал он.
100 % CPU — это одно ядро.
Native-образ:
| Нагрузка | p95 | CPU | RAM |
|---|---|---|---|
| покой, без модели | — | 0 % | **10 МБ** |
| покой, с моделью | — | 0 % | 378 МБ |
| 5000 RPS, только правила | 3,5 мс | 208 % | 103 МБ |
| 5000 RPS, со второй ступенью | 4,6 мс | 218 % | 516 МБ |
| 8000 RPS, со второй ступенью | 25,5 мс | 257 % | 557 МБ |
| 12000 RPS, со второй ступенью | 69,2 мс | 398 % | 698 МБ |
Тот же образ на JVM, 5000 RPS. Холодный прогон — первые сорок секунд после подъёма,
прогретый — следующие:
| Нагрузка | p95 | CPU | RAM |
|---|---|---|---|
| покой, без модели | — | 0 % | 147 МБ |
| только правила, холодная | 13,8 мс | 273 % | 365 МБ |
| только правила, прогретая | **1,3 мс** | **107 %** | 433 МБ |
| со ступенью, холодная | 18,5 мс | 150 % | 590 МБ |
| со ступенью, прогретая | **1,9 мс** | 136 % | 640 МБ |
Отказов на всех прогонах ноль, пары восстановлены полностью.
**Прогретая JVM обгоняет native** — вдвое по процессору и втрое по задержке: C2
оптимизирует по факту исполнения и обходит опережающую компиляцию. Расплата —
первые десятки секунд: у холодной JVM p95 в четыре раза хуже, отдельные запросы
доходят до полутора секунд. Native же одинаков с первой секунды.
Выбор зависит от того, как запускается сервис. Долгоживущий процесс за
балансировщиком — JVM выгоднее, прогрев окупается за минуту. Частые перезапуски,
масштабирование по нагрузке или короткий прогон целиком — native предсказуемее.
Память: native расходует втрое-вчетверо меньше.
Вторая ступень почти не добавляет процессора: на этих запросах правила разбирают
всё сами, и модель до кандидатов не доходит. Зато она стоит около 370 МБ памяти —
это файл модели, и он не зависит от нагрузки.
На целевых 1000 RPS сервису достаточно **половины ядра и порядка 150 МБ** без
модели или 500 МБ с ней.
Два узла с общим слоем в Redis, обратный шаг **всегда** попадает на другой узел —
худший возможный случай: