P1: Нагрузочное тестирование IFT (Tsung с дев-машины, 1 нода) #30

Closed
opened 2026-07-15 00:04:31 +03:00 by cursor-ai · 23 comments
Owner

Проблема

Нужен воспроизводимый нагрузочный прогон backend на IFT: только Traefik + eventhub, генератор с дев-машины. Старый сценарий test/tsung устарел (thinktime в секундах, dummy refresh, один линейный path).

Ожидаемый результат

  • Скрипты prepare/restore в EventHubDevOps (EVENTHUB_REPLICAS, default 1)
  • Оптимизированные tsung-профили: smoke + mixed sessions (browse/create)
  • README с порядком запуска

Критерии приёмки

  • prepare оставляет traefik + eventhub (N нод), гасит admin/bot/observability/fallback
  • restore возвращает штатный IFT
  • eventhub_ift.xml / eventhub_ift_smoke.xml на api.ift.eventhub.local:443 SSL
  • README: WSL tsung, фазы нагрузки, уникальные email/start_time

Приоритет

P1

## Проблема Нужен воспроизводимый нагрузочный прогон backend на IFT: только Traefik + eventhub, генератор с дев-машины. Старый сценарий test/tsung устарел (thinktime в секундах, dummy refresh, один линейный path). ## Ожидаемый результат - Скрипты prepare/restore в EventHubDevOps (EVENTHUB_REPLICAS, default 1) - Оптимизированные tsung-профили: smoke + mixed sessions (browse/create) - README с порядком запуска ## Критерии приёмки - [ ] prepare оставляет traefik + eventhub (N нод), гасит admin/bot/observability/fallback - [ ] restore возвращает штатный IFT - [ ] eventhub_ift.xml / eventhub_ift_smoke.xml на api.ift.eventhub.local:443 SSL - [ ] README: WSL tsung, фазы нагрузки, уникальные email/start_time ## Приоритет P1
cursor-ai self-assigned this 2026-07-15 00:04:31 +03:00
Author
Owner

Беру в работу: prepare/restore IFT + оптимизированные tsung-профили.

Беру в работу: prepare/restore IFT + оптимизированные tsung-профили.
Author
Owner

Stress hot-path на IFT выполнен (поиск верхней границы, критерий 2A).

Артефакты

  • test/tsung/eventhub_ift_stress.xml (+ bump)
  • test/tsung/seed-ift-users.shift-users.csv (400 пользователей)
  • test/tsung/summarize-tsung-stress.py
  • оркестратор: run-ift-loadtest.sh stress

Прогон ~/.tsung/log/20260715-1027/ (ladder 0.05→0.006 s, maxusers=5000, без thinktime):

  • сессии: started 5055 / finished 695
  • HTTP 2xx: 396 (200=361, 201=35)
  • transport: connect_closed=2187, timeout=203, abort_max_conn_retries=437
  • mean request ~735 ms, peak interval mean ~120 s
  • verdict=BOUNDARY_HIT (error rate ~88% и mean >500 ms)

Уже на ранней нагрузке без thinktime IFT упёрся: клиент набрал тысячи hung VU, SSH banner/API временно клинили. В XML после прогона: maxusers=800 и более мягкий ladder.

Bump-профиль не запускался — граница уже найдена.

Stress hot-path на IFT выполнен (поиск верхней границы, критерий 2A). **Артефакты** - `test/tsung/eventhub_ift_stress.xml` (+ bump) - `test/tsung/seed-ift-users.sh` → `ift-users.csv` (400 пользователей) - `test/tsung/summarize-tsung-stress.py` - оркестратор: `run-ift-loadtest.sh stress` **Прогон** `~/.tsung/log/20260715-1027/` (ladder 0.05→0.006 s, maxusers=5000, без thinktime): - сессии: started 5055 / finished 695 - HTTP 2xx: 396 (200=361, 201=35) - transport: connect_closed=2187, timeout=203, abort_max_conn_retries=437 - mean request ~735 ms, peak interval mean ~120 s - **verdict=BOUNDARY_HIT** (error rate ~88% и mean >500 ms) Уже на ранней нагрузке без thinktime IFT упёрся: клиент набрал тысячи hung VU, SSH banner/API временно клинили. В XML после прогона: `maxusers=800` и более мягкий ladder. Bump-профиль не запускался — граница уже найдена.
Author
Owner

Controlled hold на IFT (поиск зелёного потолка).

Профиль: eventhub_ift_stress_hold.xml (maxusers=300, thinktime=1s, ladder 0.2→0.1→0.05→0.035).
Лог: ~/.tsung/log/20260715-1200/.

По фазам:

  • interarrival 0.2 и 0.1 (~5–10 VU/s): GREEN — mean ≈35 ms, 0 transport errors;
  • interarrival 0.05 (~20 VU/s): OVER — всплески latency, 290 timeout на фазе (~17%);
  • итог прогона: mean ~109 ms, error rate ~2.9% → BOUNDARY_HIT по критерию 2A, но устойчивый потолок ясен.

Вывод: на IFT×1 hot-path безопасный режим — до ~10 новых VU/s (при thinktime=1s). Выше — connect/timeout деградация; на 0.05 снова возможен клин SSH (нужен reboot + restore).

Оркестратор: run-ift-loadtest.sh stress-hold.
IFT после последнего reboot восстановлен (eventhub×2, smoke-core OK).

Controlled hold на IFT (поиск зелёного потолка). Профиль: `eventhub_ift_stress_hold.xml` (maxusers=300, thinktime=1s, ladder 0.2→0.1→0.05→0.035). Лог: `~/.tsung/log/20260715-1200/`. По фазам: - interarrival 0.2 и 0.1 (~5–10 VU/s): GREEN — mean ≈35 ms, 0 transport errors; - interarrival 0.05 (~20 VU/s): OVER — всплески latency, 290 timeout на фазе (~17%); - итог прогона: mean ~109 ms, error rate ~2.9% → BOUNDARY_HIT по критерию 2A, но устойчивый потолок ясен. Вывод: на IFT×1 hot-path безопасный режим — до ~10 новых VU/s (при thinktime=1s). Выше — connect/timeout деградация; на 0.05 снова возможен клин SSH (нужен reboot + restore). Оркестратор: `run-ift-loadtest.sh stress-hold`. IFT после последнего reboot восстановлен (eventhub×2, smoke-core OK).
Author
Owner

Сравнение controlled hold: eventhub×1 vs ×2 (один и тот же eventhub_ift_stress_hold.xml).

×1 (20260715-1200) ×2 (20260715-1336)
phase 0.2 / 0.1 (~5–10 VU/s) GREEN, mean≈35 ms GREEN, mean≈37 ms
phase 0.05 (~20 VU/s) OVER, timeout 290 (~17%) OVER мягче, timeout 106 (~3%)
overall mean ~109 ms ~64 ms
overall error rate ~2.9% → BOUNDARY_HIT ~0.94% → UNDER_THRESHOLD

Вывод: зелёный потолок тот же (~10 VU/s). Две ноды не поднимают «зелёную» arrival-границу, но заметно смягчают деградацию на 20 VU/s и удерживают прогон ниже порога 2A в среднем. Клин SSH на фазе 0.05 возможен и при ×2 — для hold лучше не заходить выше 0.1 без отдельного лимита.

Сравнение controlled hold: eventhub×1 vs ×2 (один и тот же `eventhub_ift_stress_hold.xml`). | | ×1 (`20260715-1200`) | ×2 (`20260715-1336`) | |--|--|--| | phase 0.2 / 0.1 (~5–10 VU/s) | GREEN, mean≈35 ms | GREEN, mean≈37 ms | | phase 0.05 (~20 VU/s) | OVER, timeout 290 (~17%) | OVER мягче, timeout 106 (~3%) | | overall mean | ~109 ms | ~64 ms | | overall error rate | ~2.9% → BOUNDARY_HIT | ~0.94% → UNDER_THRESHOLD | Вывод: зелёный потолок тот же (~10 VU/s). Две ноды не поднимают «зелёную» arrival-границу, но заметно смягчают деградацию на 20 VU/s и удерживают прогон ниже порога 2A в среднем. Клин SSH на фазе 0.05 возможен и при ×2 — для hold лучше не заходить выше 0.1 без отдельного лимита.
Author
Owner

Hold ×3 (EVENTHUB_REPLICAS=3, тот же eventhub_ift_stress_hold.xml), лог ~/.tsung/log/20260715-1411/.

По connect (фаза → transport):

  • 0.2 / 0.1 / 0.05: GREEN (mean ≈35–40 ms, 0 timeout)
  • 0.035: GREEN по transport (err 0.1%, mean≈441 ms)

Overall: BOUNDARY_HIT — 3772× HTTP 429, mean ~44 ms, transport почти нет (19 closed).

Вывод vs ×1/×2: три ноды снимают connect-storm на 20 VU/s; узкое место становится rate limit (429). Зелёный connect-потолок поднимается; «успешный HTTP» потолок упирается в throttle.

Restore: в оркестраторе добавлен fallback WSL→Windows (restore-ift.ps1). После этого прогона SSH banner снова клинит — нужен reboot + restore.

Hold ×3 (`EVENTHUB_REPLICAS=3`, тот же `eventhub_ift_stress_hold.xml`), лог `~/.tsung/log/20260715-1411/`. По connect (фаза → transport): - 0.2 / 0.1 / **0.05**: GREEN (mean ≈35–40 ms, 0 timeout) - 0.035: GREEN по transport (err 0.1%, mean≈441 ms) Overall: BOUNDARY_HIT — **3772× HTTP 429**, mean ~44 ms, transport почти нет (19 closed). Вывод vs ×1/×2: три ноды снимают connect-storm на 20 VU/s; узкое место становится **rate limit (429)**. Зелёный connect-потолок поднимается; «успешный HTTP» потолок упирается в throttle. Restore: в оркестраторе добавлен fallback WSL→Windows (`restore-ift.ps1`). После этого прогона SSH banner снова клинит — нужен reboot + restore.
Author
Owner

Итог: нагрузочное тестирование IFT завершено

Стенд восстановлен (eventhub 2/2, traefik 1/1, health API/admin OK).

Профили

Прогон Результат
Smoke OK
Full soft OK (~112 VU, mean ~62 ms, 0% ошибок)
Stress aggressive BOUNDARY_HIT, клин WSL/vmmem/SSH
Hold ×1 GREEN до ~10 VU/s; OVER с ~20 VU/s (timeouts)
Hold ×2 тот же зелёный потолок; overall UNDER_THRESHOLD
Hold ×3 connect GREEN; overall BOUNDARY_HIT из‑за HTTP 429

Выводы

  1. Рабочий потолок IFT: ~10 VU/s hot-path (interarrival ≥0.1 s, thinktime ≥1 s).
  2. ×1/×2 упираются в connect-слой (TLS/Traefik/WSL); ×3 — в приложение (429, Mnesia, archive_manager).
  3. Restore через WSL SSH часто мёртв — нужен Windows SSH / wsl --shutdown.

Подробный отчёт прикреплён ниже и лежит на exchange-share:
\\192.168.1.116\eventhub-cursor\ift-to-dev\LOADTEST-SUMMARY-2026-07-15.md

Follow-up задачи созданы отдельно (P0/P1/P2). Задачу #30 закрываю.

## Итог: нагрузочное тестирование IFT завершено Стенд восстановлен (`eventhub 2/2`, `traefik 1/1`, health API/admin OK). ### Профили | Прогон | Результат | |--------|-----------| | Smoke | OK | | Full soft | OK (~112 VU, mean ~62 ms, 0% ошибок) | | Stress aggressive | BOUNDARY_HIT, клин WSL/`vmmem`/SSH | | Hold ×1 | GREEN до ~10 VU/s; OVER с ~20 VU/s (timeouts) | | Hold ×2 | тот же зелёный потолок; overall UNDER_THRESHOLD | | Hold ×3 | connect GREEN; overall BOUNDARY_HIT из‑за **HTTP 429** | ### Выводы 1. Рабочий потолок IFT: **~10 VU/s** hot-path (interarrival ≥0.1 s, thinktime ≥1 s). 2. ×1/×2 упираются в connect-слой (TLS/Traefik/WSL); ×3 — в приложение (429, Mnesia, archive_manager). 3. Restore через WSL SSH часто мёртв — нужен Windows SSH / `wsl --shutdown`. Подробный отчёт прикреплён ниже и лежит на exchange-share: `\\192.168.1.116\eventhub-cursor\ift-to-dev\LOADTEST-SUMMARY-2026-07-15.md` Follow-up задачи созданы отдельно (P0/P1/P2). Задачу #30 закрываю.
Author
Owner

Итог нагрузочного тестирования IFT (июль 2026)

Профили

Прогон Конфиг Результат
Smoke полный auth path OK
Full onboard + browse/CRUD, мягкий thinktime OK (~112 concurrent, mean ~62 ms, 0% ошибок)
Stress aggressive без thinktime, maxusers 5000 BOUNDARY_HIT, клин SSH/vmmem
Hold ×1 thinktime 1s, ladder 0.2→0.035 GREEN до ~10 VU/s; OVER с ~20 VU/s (timeouts)
Hold ×2 то же GREEN до ~10 VU/s; на 20 VU/s мягче; overall UNDER_THRESHOLD
Hold ×3 то же connect GREEN до 0.035; overall BOUNDARY_HIT из‑за HTTP 429

Логи восстановления: \\192.168.1.116\eventhub-cursor\ift-to-dev\wsl-recover-20260715-152148\

Выводы

  1. Умеренная нагрузка (≤~10 VU/s hot-path, thinktime≥1s) на IFT устойчива.
  2. ×1/×2 упираются в connect-слой (TLS/Traefik/ОС/WSL): timeouts, hung sessions, vmmem ~8 ГБ / высокий CPU, SSH banner hang.
  3. ×3 сдвигает узкое место: connect держится, появляется 429 + Mnesia overloaded + archive_manager timeout.
  4. IFT крутится в WSL2 на Windows (HOME-PC) — деградация гостя = vmmem на хосте; restore через WSL SSH часто мёртв, нужен Windows SSH / wsl --shutdown.

Рекомендации (по приоритету)

P0 — стабилизация стенда

  • После stress: restart-wsl-and-collect-logs.ps1 / wsl --shutdown, затем restore.
  • Не гонять hold ниже interarrival 0.1 без лимита maxusers и без наблюдения.
  • Починить restore при update out of sequence (retry/force update сервисов).

P1 — приложение / данные (причина 429 и падений под ×3)

  • Разобрать HTTP 429: лимитер (чей), пороги, нужен ли отдельный bypass для loadtest.
  • archive_manager timeout на get_node("YYYYMM") / peer:start_it — таймауты, пул peer-нод, не блокировать hot-path.
  • Mnesia overloaded — размер dump_log, нагрузка записи, рассмотреть Postgres для hot path / меньше sync writes на loadtest.
  • Traefik: Docker API client 1.24 → ≥1.44 (сейчас provider docker в постоянной ERR).

P2 — capacity / процесс

  • Рабочий потолок для планирования: ~10 VU/s hot-path на текущем железе; выше — только с тюнингом.
  • Hold/stress только с maxusers≤300, thinktime≥1s; aggressive без лимита запретить.
  • Мониторинг во время прогона: docker stats + Mnesia warnings + очередь archive.
  • Отдельная задача: сравнить hold на «чистом» Linux-хосте без WSL2 (если появится).
## Итог нагрузочного тестирования IFT (июль 2026) ### Профили | Прогон | Конфиг | Результат | |--------|--------|-----------| | Smoke | полный auth path | OK | | Full | onboard + browse/CRUD, мягкий thinktime | OK (~112 concurrent, mean ~62 ms, 0% ошибок) | | Stress aggressive | без thinktime, maxusers 5000 | BOUNDARY_HIT, клин SSH/vmmem | | Hold ×1 | thinktime 1s, ladder 0.2→0.035 | GREEN до ~10 VU/s; OVER с ~20 VU/s (timeouts) | | Hold ×2 | то же | GREEN до ~10 VU/s; на 20 VU/s мягче; overall UNDER_THRESHOLD | | Hold ×3 | то же | connect GREEN до 0.035; overall BOUNDARY_HIT из‑за **HTTP 429** | Логи восстановления: `\\192.168.1.116\eventhub-cursor\ift-to-dev\wsl-recover-20260715-152148\` ### Выводы 1. **Умеренная нагрузка (≤~10 VU/s hot-path, thinktime≥1s)** на IFT устойчива. 2. **×1/×2 упираются в connect-слой** (TLS/Traefik/ОС/WSL): timeouts, hung sessions, **vmmem ~8 ГБ / высокий CPU**, SSH banner hang. 3. **×3 сдвигает узкое место**: connect держится, появляется **429 + Mnesia overloaded + archive_manager timeout**. 4. IFT крутится в **WSL2 на Windows (HOME-PC)** — деградация гостя = `vmmem` на хосте; restore через WSL SSH часто мёртв, нужен Windows SSH / `wsl --shutdown`. ### Рекомендации (по приоритету) **P0 — стабилизация стенда** - После stress: `restart-wsl-and-collect-logs.ps1` / `wsl --shutdown`, затем restore. - Не гонять hold ниже interarrival **0.1** без лимита maxusers и без наблюдения. - Починить restore при `update out of sequence` (retry/force update сервисов). **P1 — приложение / данные (причина 429 и падений под ×3)** - Разобрать **HTTP 429**: лимитер (чей), пороги, нужен ли отдельный bypass для loadtest. - **`archive_manager` timeout** на `get_node("YYYYMM")` / `peer:start_it` — таймауты, пул peer-нод, не блокировать hot-path. - **Mnesia overloaded** — размер dump_log, нагрузка записи, рассмотреть Postgres для hot path / меньше sync writes на loadtest. - Traefik: Docker API client **1.24 → ≥1.44** (сейчас provider docker в постоянной ERR). **P2 — capacity / процесс** - Рабочий потолок для планирования: **~10 VU/s** hot-path на текущем железе; выше — только с тюнингом. - Hold/stress только с `maxusers≤300`, thinktime≥1s; aggressive без лимита запретить. - Мониторинг во время прогона: docker stats + Mnesia warnings + очередь archive. - Отдельная задача: сравнить hold на «чистом» Linux-хосте без WSL2 (если появится).
Author
Owner

Повторный hold ×3 после фиксов #32–#34 (2026-07-15)

Образ: sha-7fa24e831c16 (rate limit 2000/1s, MNESIA_DUMP_LOG_WRITE_THRESHOLD=50000, archive async).
Профиль: stress-hold, EVENTHUB_REPLICAS=3.
Лог Tsung: ~/.tsung/log/20260715-1845/
Архив стенда: C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-195035\ (после wsl --shutdown — в docker-логах в основном перезапуск, не окно нагрузки).

Сравнение с ×3 до фиксов (20260715-1411)

До После
HTTP 429 3772 0
4xx/5xx да нет
error_rate 24% 1.018% (106 error_timeout)
mean request ~44 ms (+ late ~8 s) ~47 ms (peak interval ~118 ms)
запросов ~43k (все фазы) ~10k (обрыв ~на фазе 2)
verdict BOUNDARY_HIT (429) BOUNDARY_HIT на грани (таймауты)

Хронология

  1. ~18:45–18:49 — живой hold, latency ~40–55 ms (GREEN), вход в фазу 2 (interarrival 0.1).
  2. maxusers=300 + use_controller_vm — предупреждение Tsung; ~194 VU зависли, дальше 0 запросов.
  3. docker-stats: одна нода eventhub ~99% CPU, Traefik RAM 1.4→2.1 GiB.
  4. с ~18:50 — SSH banner timeout / API недоступен (клин WSL). Restore после wsl --shutdown.

Выводы

  • Фикс #32 сработал: 429 сняты, узкое место больше не Traefik ratelimit.
  • Latency в живой части зелёная (≪ 500 ms).
  • BOUNDARY_HIT формальный: почти целиком таймауты после залипания Tsung/WSL, не деградация HTTP API.
  • Со стендовых логов после reboot: Mnesia overloaded = 0 (окно нагрузки в них не сохранилось).

Следующий шаг (в этой задаче)

Повторить hold ×3 с безопасным потолком VU (снизить maxusers и/или отдельный client beam), чтобы дойти до фаз 0.05/0.035 без клина контроллера; продолжать записи (collect+анализ по WORKFLOW §7) здесь.

## Повторный hold ×3 после фиксов #32–#34 (2026-07-15) **Образ:** `sha-7fa24e831c16` (rate limit 2000/1s, `MNESIA_DUMP_LOG_WRITE_THRESHOLD=50000`, archive async). **Профиль:** `stress-hold`, `EVENTHUB_REPLICAS=3`. **Лог Tsung:** `~/.tsung/log/20260715-1845/` **Архив стенда:** `C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-195035\` (после `wsl --shutdown` — в docker-логах в основном перезапуск, не окно нагрузки). ### Сравнение с ×3 до фиксов (`20260715-1411`) | | До | После | |---|---|---| | HTTP 429 | 3772 | **0** | | 4xx/5xx | да | нет | | error_rate | 24% | **1.018%** (106 `error_timeout`) | | mean request | ~44 ms (+ late ~8 s) | ~47 ms (peak interval ~118 ms) | | запросов | ~43k (все фазы) | ~10k (обрыв ~на фазе 2) | | verdict | BOUNDARY_HIT (429) | BOUNDARY_HIT на грани (таймауты) | ### Хронология 1. ~18:45–18:49 — живой hold, latency ~40–55 ms (GREEN), вход в фазу 2 (interarrival 0.1). 2. `maxusers=300` + `use_controller_vm` — предупреждение Tsung; ~194 VU зависли, дальше 0 запросов. 3. docker-stats: одна нода eventhub ~99% CPU, Traefik RAM 1.4→2.1 GiB. 4. с ~18:50 — SSH banner timeout / API недоступен (клин WSL). Restore после `wsl --shutdown`. ### Выводы - Фикс #32 сработал: **429 сняты**, узкое место больше не Traefik ratelimit. - Latency в живой части **зелёная** (≪ 500 ms). - BOUNDARY_HIT формальный: почти целиком таймауты после залипания Tsung/WSL, не деградация HTTP API. - Со стендовых логов после reboot: `Mnesia overloaded` = 0 (окно нагрузки в них не сохранилось). ### Следующий шаг (в этой задаче) Повторить hold ×3 с безопасным потолком VU (снизить `maxusers` и/или отдельный client beam), чтобы дойти до фаз 0.05/0.035 без клина контроллера; продолжать записи (collect+анализ по WORKFLOW §7) здесь.
Author
Owner

Процесс: cleanup дампов + мониторинг; hold maxusers=200

Cleanup на IFT (обязательный gate)

После collect/анализа удалять дампы на стенде, чтобы не забивать FS:

  • EventHubDevOps/scripts/cleanup-ift-loadtest-dumps.sh
  • cleanup-ift-loadtest-dumps.ps1 (.cursor/eventhub + шара scripts/)
  • collect-ift-loadtest-logs.ps1 после download чистит remote dump этого stamp
  • collect-*-on-ift.sh после copy на шару чистит локальный dir+tgz

Копии на шаре / Tsung на дев не трогаем. WORKFLOW §7 и README обновлены.

Мониторинг

В анализ добавлен Grafana/Prometheus/Loglynx/observer (после restore).
Во время прогона сейчас prepare гасит observability; для скрейпа mid-run: KEEP_OBSERVABILITY=1 на prepare (оркестратор пробрасывает). На прогоне 1845 мониторинг был выключен — mid-run метрик в Prom нет.

Следующий прогон

Рекомендованный вариант: stress-hold maxusers=200 (XML обновлён), EVENTHUB_REPLICAS=3, лучше с KEEP_OBSERVABILITY=1. Записи продолжаем здесь.

## Процесс: cleanup дампов + мониторинг; hold maxusers=200 ### Cleanup на IFT (обязательный gate) После collect/анализа удалять дампы на стенде, чтобы не забивать FS: - `EventHubDevOps/scripts/cleanup-ift-loadtest-dumps.sh` - `cleanup-ift-loadtest-dumps.ps1` (`.cursor/eventhub` + шара `scripts/`) - `collect-ift-loadtest-logs.ps1` после download чистит remote dump **этого** stamp - `collect-*-on-ift.sh` после copy на шару чистит локальный dir+tgz Копии на шаре / Tsung на дев **не** трогаем. WORKFLOW §7 и README обновлены. ### Мониторинг В анализ добавлен Grafana/Prometheus/Loglynx/observer (после restore). Во время прогона сейчас prepare гасит observability; для скрейпа mid-run: `KEEP_OBSERVABILITY=1` на prepare (оркестратор пробрасывает). На прогоне 1845 мониторинг был выключен — mid-run метрик в Prom нет. ### Следующий прогон Рекомендованный вариант: `stress-hold` `maxusers=200` (XML обновлён), `EVENTHUB_REPLICAS=3`, лучше с `KEEP_OBSERVABILITY=1`. Записи продолжаем здесь.
Author
Owner

Уточнение: метрики бэка (не compose Prometheus)

Compose Prometheus во время 1845 был scale 0 — mid-run там действительно пусто.

Зато сервис EventHub пишет/отдаёт метрики сам:

  • GET https://api.ift.eventhub.local/metrics — Prometheus text (cowboy_*), без auth
  • GET /v1/admin/nodes/metrics?from=&to= — история узлов в Mnesia (admin JWT)

Запрос по окну 1845 (15:40–16:35 UTC)

614 точек, 2 ноды в выборке (node1/node2; третья в ответах за окно не попала / не писала):

node1 node2
CPU peak 61% @ 15:50Z 47% @ 15:50Z
sessions max 1033 862
mem_available min ~54 MiB @ 16:10Z то же окно
mnesia_failures (last) 64 46
run_queue max 0 0

Пик CPU ~18:50 MSK совпадает с клином SSH; к 19:10 MSK память гостя почти выжата — хорошо бьётся с Traefik RAM в docker-stats.

В gate/оркестратор: сэмплер /metrics~/.tsung/ift-eh-metrics-*.log; в анализе — ещё nodes/metrics после прогона. WORKFLOW/README поправлены: compose Prom — опционально.

## Уточнение: метрики бэка (не compose Prometheus) Compose Prometheus во время 1845 был scale 0 — mid-run там действительно пусто. Зато **сервис EventHub** пишет/отдаёт метрики сам: - `GET https://api.ift.eventhub.local/metrics` — Prometheus text (cowboy_*), без auth - `GET /v1/admin/nodes/metrics?from=&to=` — история узлов в Mnesia (admin JWT) ### Запрос по окну 1845 (15:40–16:35 UTC) `614` точек, **2** ноды в выборке (node1/node2; третья в ответах за окно не попала / не писала): | | node1 | node2 | |---|---|---| | CPU peak | **61%** @ 15:50Z | **47%** @ 15:50Z | | sessions max | **1033** | 862 | | mem_available min | **~54 MiB** @ 16:10Z | то же окно | | mnesia_failures (last) | 64 | 46 | | run_queue max | 0 | 0 | Пик CPU ~**18:50 MSK** совпадает с клином SSH; к **19:10 MSK** память гостя почти выжата — хорошо бьётся с Traefik RAM в docker-stats. В gate/оркестратор: сэмплер `/metrics` → `~/.tsung/ift-eh-metrics-*.log`; в анализе — ещё `nodes/metrics` после прогона. WORKFLOW/README поправлены: compose Prom — опционально.
Author
Owner

Прогон hold ×3 maxusers=200 (20260715-2022) — частично / клин

Профиль: stress-hold, replicas=3, maxusers=200, образ sha-7fa24e831c16.
Лог: ~/.tsung/log/20260715-2022/
Сэмплы: ift-eh-metrics-…202237.log, ift-docker-stats-…202237.log

Tsung 2A

requests 9863
HTTP 4xx/5xx 0
timeouts 175
error_rate 1.743% → BOUNDARY_HIT
mean cumul ~93 ms
peak interval mean ~1139 ms @ dump 26
фазы снова обрыв ~на фазе 2; warning maxusers/use_controller_vm
unfinished VU 16 (лучше, чем 194 при maxusers=300)

/metrics sampler

До ~20:26 MSK counters растут; с 20:27 fetch пустой → API/путь к бэку лёг.
(счётчики cowboy per-replica за LB — не глобальные, тренды по ноде.)

docker-stats

~20:25: eventhub.3 ~96% CPU, Traefik RAM ~2.5 GiB; с 20:27 SSH banner timeout.

Статус стенда

IFT снова клинило (SSH/API). Нужен wsl --shutdown на HOME-PC → collect + cleanup + restore + nodes/metrics за окно 17:20–17:45 UTC.

Вывод

maxusers=200 не хватило, чтобы дойти до фаз 0.05/0.035 без клина; 429 по-прежнему нет. Дальше: ещё снизить maxusers (например 100) и/или укоротить/смягчить фазы 3–4.

## Прогон hold ×3 maxusers=200 (`20260715-2022`) — частично / клин **Профиль:** stress-hold, replicas=3, `maxusers=200`, образ `sha-7fa24e831c16`. Лог: `~/.tsung/log/20260715-2022/` Сэмплы: `ift-eh-metrics-…202237.log`, `ift-docker-stats-…202237.log` ### Tsung 2A | | | |---|---| | requests | 9863 | | HTTP 4xx/5xx | **0** | | timeouts | **175** | | error_rate | **1.743%** → BOUNDARY_HIT | | mean cumul | ~93 ms | | peak interval mean | **~1139 ms** @ dump 26 | | фазы | снова обрыв ~на фазе 2; warning maxusers/use_controller_vm | | unfinished VU | 16 (лучше, чем 194 при maxusers=300) | ### /metrics sampler До ~20:26 MSK counters растут; с **20:27** fetch пустой → API/путь к бэку лёг. (счётчики cowboy per-replica за LB — не глобальные, тренды по ноде.) ### docker-stats ~20:25: eventhub.3 **~96% CPU**, Traefik RAM **~2.5 GiB**; с 20:27 SSH banner timeout. ### Статус стенда IFT снова клинило (SSH/API). Нужен `wsl --shutdown` на HOME-PC → collect + cleanup + restore + `nodes/metrics` за окно 17:20–17:45 UTC. ### Вывод `maxusers=200` **не хватило**, чтобы дойти до фаз 0.05/0.035 без клина; 429 по-прежнему нет. Дальше: ещё снизить maxusers (например **100**) и/или укоротить/смягчить фазы 3–4.
Author
Owner

Дополнение к 2022: nodes/metrics + артефакты

Стенд после restore ожил без ручного wsl --shutdown. Полный collect завис на docker logs — сняли вручную:

  • шара/локаль: C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-2022-partial\ (tsung log, /metrics sampler, docker-stats, node-metrics.json)

/v1/admin/nodes/metrics 17:20–17:50 UTC

node1 node2
CPU peak 99.7% @ 17:32Z 99.8% @ 17:34Z
sessions max 1448 1010
mem_available min ~11 MiB ~11 MiB
run_queue max 0 0

Вывод: при maxusers=200 стенд всё равно уходит в CPU/RAM saturation и клин; 429 нет. Следующий шаг — maxusers=100 (и/или смягчить фазы 3–4).

## Дополнение к 2022: `nodes/metrics` + артефакты Стенд после restore ожил без ручного `wsl --shutdown`. Полный `collect` завис на docker logs — сняли вручную: - шара/локаль: `C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-2022-partial\` (tsung log, `/metrics` sampler, docker-stats, `node-metrics.json`) ### `/v1/admin/nodes/metrics` 17:20–17:50 UTC | | node1 | node2 | |---|---|---| | CPU peak | **99.7%** @ 17:32Z | **99.8%** @ 17:34Z | | sessions max | **1448** | 1010 | | mem_available min | **~11 MiB** | ~11 MiB | | run_queue max | 0 | 0 | Вывод: при maxusers=200 стенд всё равно уходит в **CPU/RAM saturation** и клин; 429 нет. Следующий шаг — **maxusers=100** (и/или смягчить фазы 3–4).
Author
Owner

Запускаю hold ×3 с maxusers=100 (образ sha-7fa24e831c16). После — стандартный gate: summary, /metrics sampler, nodes/metrics, collect, cleanup, restore.

Запускаю hold ×3 с `maxusers=100` (образ `sha-7fa24e831c16`). После — стандартный gate: summary, /metrics sampler, nodes/metrics, collect, cleanup, restore.
Author
Owner

Прогон hold ×3 maxusers=100 (20260715-2102) — UNDER_THRESHOLD

Образ: sha-7fa24e831c16, replicas=3.
Артефакты: C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-2102\

Tsung 2A

users 1917/1917 finished
requests 9585
HTTP 4xx/5xx 0
transport errors 0
error_rate 0%
mean cumul ~115 ms
late interval mean ~331 ms
peak interval ~2141 ms @ dump 26 (хвост)
verdict UNDER_THRESHOLD
фазы только 1→2 (0.2 / 0.1); dumps=27 (~4 мин). Фазы 0.05/0.035 не стартовали (после warning maxusers/use_controller_vm новые VU не поднимаются)

nodes/metrics (18:00–18:13 UTC)

node1 node2
CPU peak 57.7% 59.8%
sessions max 1309 1172
mem_available min ~335 MiB ~342 MiB

Мягче, чем при maxusers=200 (~100% CPU / ~11 MiB). SSH/restore без клина.

Вывод

  • Устойчивый зелёный hold на ~10 VU/s (фаза 0.1) при ×3 и maxusers=100.
  • Чтобы измерить 0.05/0.035 без клина контроллера — отдельный профиль (без use_controller_vm / другой client) или урезанная arrival без заполнения слотов до hard-stop beam.
## Прогон hold ×3 maxusers=100 (`20260715-2102`) — UNDER_THRESHOLD **Образ:** `sha-7fa24e831c16`, replicas=3. Артефакты: `C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-2102\` ### Tsung 2A | | | |---|---| | users | 1917/1917 finished | | requests | 9585 | | HTTP 4xx/5xx | **0** | | transport errors | **0** | | error_rate | **0%** | | mean cumul | ~115 ms | | late interval mean | ~331 ms | | peak interval | ~2141 ms @ dump 26 (хвост) | | verdict | **UNDER_THRESHOLD** | | фазы | только **1→2** (0.2 / 0.1); dumps=27 (~4 мин). Фазы 0.05/0.035 **не стартовали** (после warning maxusers/use_controller_vm новые VU не поднимаются) | ### nodes/metrics (18:00–18:13 UTC) | | node1 | node2 | |---|---|---| | CPU peak | 57.7% | 59.8% | | sessions max | 1309 | 1172 | | mem_available min | ~335 MiB | ~342 MiB | Мягче, чем при maxusers=200 (~100% CPU / ~11 MiB). SSH/restore без клина. ### Вывод - Устойчивый зелёный hold на **~10 VU/s** (фаза 0.1) при ×3 и maxusers=100. - Чтобы измерить 0.05/0.035 без клина контроллера — отдельный профиль (без use_controller_vm / другой client) или урезанная arrival без заполнения слотов до hard-stop beam.
Author
Owner

stress-hold-beams ×3 (20260715-2119) — ОТМЕНА / опасно

Профиль use_controller_vm=false + cpu=2 раздул slave beams: concurrent ~4800 VU, freemem контроллера падал до ~0.5–0.6 GiB, Tsung убит (exit 137).

users started/finished 6673 / 2551
HTTP 4xx 0
transport 3230 connect_closed + 105 timeout + 646 abort → error 30%
verdict BOUNDARY_HIT
IFT SSH/API клин; restore fail

Профиль помечен как опасный (нужен CONFIRM_DANGEROUS=1), не использовать для IFT по умолчанию.

Нужен wsl --shutdown на HOME-PC → collect/restore.

Альтернатива для фаз 0.05/0.035: отдельный stress-hold-hot только с этими фазами и use_controller_vm=true / maxusers=100 (без slave beams).

## stress-hold-beams ×3 (`20260715-2119`) — ОТМЕНА / опасно Профиль `use_controller_vm=false` + `cpu=2` раздул slave beams: concurrent **~4800 VU**, freemem контроллера падал до ~0.5–0.6 GiB, Tsung убит (exit 137). | | | |---|---| | users started/finished | 6673 / 2551 | | HTTP 4xx | 0 | | transport | 3230 connect_closed + 105 timeout + 646 abort → **error 30%** | | verdict | BOUNDARY_HIT | | IFT | SSH/API клин; restore fail | Профиль помечен как **опасный** (нужен `CONFIRM_DANGEROUS=1`), не использовать для IFT по умолчанию. Нужен `wsl --shutdown` на HOME-PC → collect/restore. Альтернатива для фаз 0.05/0.035: отдельный `stress-hold-hot` только с этими фазами и `use_controller_vm=true` / maxusers=100 (без slave beams).
Author
Owner

Логи после wsl --shutdown (loadtest-20260715-214518)

Архив: C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-214518\ (+ tsung 20260715-2119). Restore выполнен, smoke зелёный.

Важно из eventhub-service.log

  1. MNESIA_DUMP_LOG_WRITE_THRESHOLD не применяется: на всех нодах
    Mnesia dump_log_write_threshold change failed: {error, dump_log_write_threshold}
    (нужно чинить infra_mnesia:configure_dump_log/0 — параметр/API OTP).
  2. Под нагрузкой (окно ~17:31–17:45Z, прогон maxusers=200):
    Mnesia is overloaded: {dump_log, time_threshold} ×4 на node3.
  3. После kill WSL: tasks exit 255, ошибки Mnesia loader / partitioned network при рестарте — типичный грязный shutdown, не первопричина клина.
  4. traefik-service.log пустой (хвост после restart). dmesg без OOM.
  5. Tsung beams (2119): уже известный BOUNDARY_HIT err 30% / ~4800 VU.

Стенд готов к stress-hold-hot.

## Логи после wsl --shutdown (`loadtest-20260715-214518`) Архив: `C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260715-214518\` (+ tsung `20260715-2119`). Restore выполнен, smoke зелёный. ### Важно из eventhub-service.log 1. **`MNESIA_DUMP_LOG_WRITE_THRESHOLD` не применяется:** на всех нодах `Mnesia dump_log_write_threshold change failed: {error, dump_log_write_threshold}` (нужно чинить `infra_mnesia:configure_dump_log/0` — параметр/API OTP). 2. Под нагрузкой (окно ~17:31–17:45Z, прогон maxusers=200): `Mnesia is overloaded: {dump_log, time_threshold}` ×4 на node3. 3. После kill WSL: tasks `exit 255`, ошибки Mnesia loader / partitioned network при рестарте — типичный грязный shutdown, не первопричина клина. 4. `traefik-service.log` пустой (хвост после restart). dmesg без OOM. 5. Tsung beams (2119): уже известный BOUNDARY_HIT err 30% / ~4800 VU. Стенд готов к `stress-hold-hot`.
Author
Owner

Беру в работу (вариант 1 + лестница реплик).

План

  1. Mnesia: dump_log_write_threshold выставлять до mnesia:start (сейчас change_config молча падает — порог не действует).
  2. Traefik IFT loadtest: в prepare — профиль без WAF (rate limit 2000/1s оставляем как safety); в restore — вернуть обычный dynamic_conf.
  3. Пересчёт потолка: сначала ×1 нода (базовый ceiling без репликации Mnesia), затем ×2, ×3 — чтобы отделить эффект репликации БД от raw capacity. Профиль: stress-hold / stress-hold-hot, gate collect/metrics/cleanup/отчёт в #30.

Не трогаем stress-hold-beams без отдельного подтверждения.

Беру в работу (вариант 1 + лестница реплик). ## План 1. **Mnesia**: dump_log_write_threshold выставлять **до** mnesia:start (сейчас change_config молча падает — порог не действует). 2. **Traefik IFT loadtest**: в prepare — профиль без WAF (rate limit 2000/1s оставляем как safety); в restore — вернуть обычный dynamic_conf. 3. **Пересчёт потолка**: сначала **×1** нода (базовый ceiling без репликации Mnesia), затем **×2**, **×3** — чтобы отделить эффект репликации БД от raw capacity. Профиль: stress-hold / stress-hold-hot, gate collect/metrics/cleanup/отчёт в #30. Не трогаем stress-hold-beams без отдельного подтверждения.
Author
Owner

Прогон потолка ×1 (после deploy sha-6d8f02d)

  • Профиль: stress-hold, EVENTHUB_REPLICAS=1, LOADTEST_TRAEFIK=1
  • Tsung: ~/.tsung/log/20260716-2143/
  • Логи IFT: C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260716-214912
  • verdict=BOUNDARY_HIT (latency): error_rate 0%, http 4xx/5xx 0, mean ~613 ms, late ~6.9 s
  • Ранняя фаза interarrival 0.2: mean ~55 ms (GREEN); на 100 concurrent latency растёт (одна нода)
  • maxusers hard-stop; users 799/799 finished
  • Register на ×2 после fix ram_copies: 5/5 × 201 (до прогона)

Следующее: EVENTHUB_REPLICAS=2 тот же профиль для сравнения репликации.

## Прогон потолка ×1 (после deploy sha-6d8f02d) - Профиль: `stress-hold`, `EVENTHUB_REPLICAS=1`, `LOADTEST_TRAEFIK=1` - Tsung: `~/.tsung/log/20260716-2143/` - Логи IFT: `C:\eventhub-cursor-exchange\ift-to-dev\loadtest-20260716-214912` - **verdict=BOUNDARY_HIT** (latency): error_rate **0%**, http 4xx/5xx **0**, mean ~**613 ms**, late ~**6.9 s** - Ранняя фаза interarrival 0.2: mean ~**55 ms** (GREEN); на 100 concurrent latency растёт (одна нода) - maxusers hard-stop; users 799/799 finished - Register на ×2 после fix ram_copies: 5/5 × 201 (до прогона) Следующее: `EVENTHUB_REPLICAS=2` тот же профиль для сравнения репликации.
Author
Owner

Прогон потолка ×2

  • Профиль: stress-hold, EVENTHUB_REPLICAS=2, образ sha-6d8f02d
  • Tsung: ~/.tsung/log/20260716-2152/
  • verdict=UNDER_THRESHOLD: error_rate 0%, 0×4xx/5xx, mean ~64 ms, late ~210 ms, peak interval ~1323 ms
  • users 1891/1891; hard-stop maxusers=100
  • Сравнение с ×1: ×1 BOUNDARY по latency (mean ~613 ms); ×2 зелёный — 2 ноды снимают latency-потолок

Дальше: ×3.

## Прогон потолка ×2 - Профиль: `stress-hold`, `EVENTHUB_REPLICAS=2`, образ `sha-6d8f02d` - Tsung: `~/.tsung/log/20260716-2152/` - **verdict=UNDER_THRESHOLD**: error_rate **0%**, 0×4xx/5xx, mean ~**64 ms**, late ~**210 ms**, peak interval ~1323 ms - users 1891/1891; hard-stop maxusers=100 - Сравнение с ×1: ×1 BOUNDARY по latency (mean ~613 ms); ×2 зелёный — 2 ноды снимают latency-потолок Дальше: ×3.
Author
Owner

Прогон потолка ×3

  • Профиль: stress-hold, EVENTHUB_REPLICAS=3, образ sha-6d8f02d
  • Tsung: ~/.tsung/log/20260716-2200/
  • verdict=UNDER_THRESHOLD: error_rate 0%, 0×4xx/5xx, mean ~44 ms, late ~48 ms, peak interval ~69 ms
  • users 2152/2152; hard-stop maxusers=100

Сводка лестницы (stress-hold, maxusers=100)

replicas verdict mean late errors
×1 BOUNDARY_HIT (latency) ~613 ms ~6.9 s 0%
×2 UNDER_THRESHOLD ~64 ms ~210 ms 0%
×3 UNDER_THRESHOLD ~44 ms ~48 ms 0%

Вывод: на текущем IFT одна нода упирается в latency при ~100 concurrent; ×2/×3 держат hold зелёным. Репликация Mnesia не ухудшает latency — наоборот, снимает потолок одной ноды.

## Прогон потолка ×3 - Профиль: `stress-hold`, `EVENTHUB_REPLICAS=3`, образ `sha-6d8f02d` - Tsung: `~/.tsung/log/20260716-2200/` - **verdict=UNDER_THRESHOLD**: error_rate **0%**, 0×4xx/5xx, mean ~**44 ms**, late ~**48 ms**, peak interval ~69 ms - users 2152/2152; hard-stop maxusers=100 ### Сводка лестницы (stress-hold, maxusers=100) | replicas | verdict | mean | late | errors | |---|---|---|---|---| | ×1 | BOUNDARY_HIT (latency) | ~613 ms | ~6.9 s | 0% | | ×2 | UNDER_THRESHOLD | ~64 ms | ~210 ms | 0% | | ×3 | UNDER_THRESHOLD | ~44 ms | ~48 ms | 0% | Вывод: на текущем IFT одна нода упирается в latency при ~100 concurrent; ×2/×3 держат hold зелёным. Репликация Mnesia не ухудшает latency — наоборот, снимает потолок одной ноды.
Author
Owner

stress-hold-hot ×3

  • Профиль: stress-hold-hot (0.1→0.05→0.035), EVENTHUB_REPLICAS=3, sha-6d8f02d
  • Tsung: ~/.tsung/log/20260716-2229/
  • verdict=UNDER_THRESHOLD: error 0%, mean ~47 ms, late ~78 ms, peak interval ~199 ms
  • users 1324/1324; hard-stop maxusers=100 (быстрее заполняет пул concurrent)

Смысл

На ×3 при лимите 100 concurrent даже «горячий» arrival не пробивает 2A: сервер держит. Узкое место профиля — maxusers/use_controller_vm, а не backend (в этих рамках). Чтобы давить выше concurrent — нужен другой профиль (осторожно) или поднять maxusers с наблюдением.

Baseline IFT (hold): зелёный потолок при ×2/×3 ~100 concurrent / hot-path; ×1 — latency BOUNDARY.

## stress-hold-hot ×3 - Профиль: `stress-hold-hot` (0.1→0.05→0.035), `EVENTHUB_REPLICAS=3`, `sha-6d8f02d` - Tsung: `~/.tsung/log/20260716-2229/` - **verdict=UNDER_THRESHOLD**: error **0%**, mean ~**47 ms**, late ~**78 ms**, peak interval ~199 ms - users 1324/1324; hard-stop maxusers=100 (быстрее заполняет пул concurrent) ### Смысл На ×3 при лимите 100 concurrent даже «горячий» arrival не пробивает 2A: сервер держит. Узкое место профиля — `maxusers`/`use_controller_vm`, а не backend (в этих рамках). Чтобы давить выше concurrent — нужен другой профиль (осторожно) или поднять maxusers с наблюдением. Baseline IFT (hold): зелёный потолок при ×2/×3 ~100 concurrent / hot-path; ×1 — latency BOUNDARY.
Author
Owner

stress-hold maxusers=150 ×3

  • Профиль: stress-hold-mu150, EVENTHUB_REPLICAS=3, sha-6d8f02d
  • Tsung: ~/.tsung/log/20260716-2241/
  • verdict=BOUNDARY_HIT (late latency): error 0%, 0×4xx/5xx, mean ~116 ms, late ~1.45 s, peak interval ~7.8 s
  • users 2421/2421; concurrent peak 150

Смысл

При 150 concurrent ошибки ещё нет, но к концу фаз ответы уезжают >500 ms → по критерию 2A это уже за границей. Рабочий зелёный concurrent на ×3 остаётся ~100; 150 — мягкий OVER по latency (без клина WSL).

До 200 пока не идём.

## stress-hold maxusers=150 ×3 - Профиль: `stress-hold-mu150`, `EVENTHUB_REPLICAS=3`, `sha-6d8f02d` - Tsung: `~/.tsung/log/20260716-2241/` - **verdict=BOUNDARY_HIT** (late latency): error **0%**, 0×4xx/5xx, mean ~**116 ms**, late ~**1.45 s**, peak interval ~7.8 s - users 2421/2421; concurrent peak 150 ### Смысл При 150 concurrent ошибки ещё нет, но к концу фаз ответы уезжают >500 ms → по критерию 2A это уже за границей. Рабочий зелёный concurrent на ×3 остаётся **~100**; 150 — мягкий OVER по latency (без клина WSL). До 200 пока не идём.
Author
Owner

Итог — закрываем

На IFT (WSL2) выяснили всё, что стенд позволяет. Дальнейшие абсолютные замеры capacity — на bare Linux (EventHubDevOps#4).

Что выяснили

  • ×1 при ~100 concurrent — BOUNDARY по latency (сервис жив, но тормозит).
  • ×2 / ×3, maxusers=100 — зелёный hold (0 errors, mean ~40–65 ms).
  • Hot ×3 (0.05/0.035) при maxusers=100 — тоже зелёный.
  • maxusers=150 на ×3 — soft OVER (late ~1.5 s), без клина WSL.
  • Фиксы по пути: Traefik rate limit, dump_log threshold до старта Mnesia, ram_copies на join-нодах (verification/session).

Prod-ориентир с IFT

Минимум 2 реплики EventHub; VU/CPU с WSL не копировать 1:1.

Baseline зафиксирован в EventHubSpec/WORKFLOW.md §7 и test/tsung/README.md.

## Итог — закрываем На IFT (WSL2) выяснили всё, что стенд позволяет. Дальнейшие абсолютные замеры capacity — на bare Linux (`EventHubDevOps#4`). ### Что выяснили - **×1** при ~100 concurrent — BOUNDARY по latency (сервис жив, но тормозит). - **×2 / ×3**, maxusers=100 — зелёный hold (0 errors, mean ~40–65 ms). - **Hot** ×3 (0.05/0.035) при maxusers=100 — тоже зелёный. - **maxusers=150** на ×3 — soft OVER (late ~1.5 s), без клина WSL. - Фиксы по пути: Traefik rate limit, dump_log threshold до старта Mnesia, ram_copies на join-нодах (verification/session). ### Prod-ориентир с IFT Минимум **2** реплики EventHub; VU/CPU с WSL не копировать 1:1. Baseline зафиксирован в `EventHubSpec/WORKFLOW.md` §7 и `test/tsung/README.md`.
Sign in to join this conversation.