Оценка нагрузочной ёмкости dix.su¶
Снимок на 2026-07-09. Данные получены с прод-сервера (ssh -p 1022 root@217.114.43.49).
Аппаратная база (VPS)¶
| Параметр | Значение |
|---|---|
| CPU | 1 × AMD EPYC (Eng Sample) |
| RAM | 1.9 GB (доступно ~631 MB, ещё ~835 MB в buff/cache) |
| Диск | 30 GB, занято 16 GB (55%), свободно 13 GB |
| ОС | Debian GNU/Linux 12 (bookworm), ядро 6.1 |
| Нагрузка в покое | load average 0.03 / 0.09 / 0.08 |
Текущее потребление ресурсов¶
| Контейнер | CPU % | RAM |
|---|---|---|
| dixu_proxy (Elixir/BEAM) | 0.17% | 328 MB |
| modulauth (Java ZGC) | 0.29% | 386 MB |
| screenshotter (Node/Playwright) | 0.00% | 101 MB |
| postgres | 0.02% | 52 MB |
| nginx | 0.00% | 15 MB |
| redis | 4.07% | 10 MB |
| certbot | 0.00% | 9 MB |
| Итого | ~4.5% | ~901 MB |
Redis показывает 4% — это артефакт персистентности (appendonly yes): периодический fsync дискового журнала. В реальном времени Redis практически не нагружен (1 ops/sec, 2 подключения).
Компонентный анализ¶
nginx¶
- Конфигурация:
worker_processes auto→ при 1 CPU = 1 worker - Лимит соединений:
worker_connections 1024(только 1 worker → максимум 1024 одновременных TCP-соединений) - TLS: терминируется nginx, certbot обновляет сертификаты Let's Encrypt автоматически
- E2E-трафик: через
stream{}сssl_preread— не терминируется, слепой relay на dixu_proxy:9443 - Потолок nginx: 1024 одновременных соединений от внешних клиентов
dixu_proxy (Elixir/Phoenix/BEAM)¶
- Erlang-планировщики: 1 (однопоточный планировщик — единственный CPU)
- Текущее количество процессов: 569 (лимит — 1 048 576)
- Память BEAM: 478 MB всего, из которых под процессы — 27 MB
- Порты Erlang: 27 открыто (лимит 65 536)
- ETS-таблиц: 115
- Pool базы данных:
POOL_SIZE=10(10 соединений к Postgres)
Каждое подключённое устройство (device_client) = 1 Phoenix-канал = ~5–10 BEAM-процессов. При 27 MB на 569 процессов → ~47 KB/процесс в среднем. Один канал устройства: ~250–500 KB памяти + overhead бинарных данных при активном трафике.
Оценка: ~300–500 одновременно подключённых устройств до достижения RAM-потолка в dixu_proxy.
Ограничивающий фактор для пропускной способности — 1 планировщик BEAM: все сообщения между процессами (http_request_, http_response_ события канала) сериализуются через один поток. I/O (сеть, диск) неблокирующий, но CPU-часть — однопоточная.
modulauth (Spring Boot WebFlux / R2DBC)¶
- Потоков JVM: 37 (37 задач в
/proc/1/task) - Куча:
-Xms256m -Xmx768m, GC — ZGC (low-latency) - R2DBC: реактивный пул к Postgres (по умолчанию ~10–20 соединений)
- Реактивная модель: Spring WebFlux не блокирует потоки на I/O; 37 потоков могут обслуживать сотни параллельных HTTP-запросов
Modulauth — не узкое место для пользовательских запросов при текущем масштабе.
PostgreSQL¶
max_connections = 100(жёсткий потолок)- Текущих соединений: 17 (из 100)
- Использование: dixu_proxy pool = 10, modulauth R2DBC pool ≈ 10–20, системные = 3–5
- Размер БД: 260 MB
- Данных в таблицах: фактически минимально (см.
n_live_tup— система только начала наполняться)
При max_connections=100 с двумя пулами по 10–20 соединений запас составляет ~50–60 дополнительных соединений. Если добавятся новые компоненты или вырастет нагрузка аналитических запросов — max_connections нужно поднять (в postgresql.conf контейнера или через env).
Redis¶
- Использование памяти: 1.18 MB (фактически пуст — только сессии Spring Security)
- Подключений: 2
- Операций/сек: ~1 (в покое)
- Лимит памяти: не задан (
maxmemory 0B= unlimited, ограничен только RAM сервера)
Redis — не узкое место даже при росте пользователей на порядок.
Оценка пропускной способности¶
Одновременно подключённых устройств (device_client)¶
| Ресурс | Лимит | Текущее | Запас |
|---|---|---|---|
| BEAM-процессы | 1 048 576 | 569 | ~1 000 000 |
| RAM dixu_proxy | ~400 MB свободно | 328 MB | ~200–400 устройств |
| Порты Erlang | 65 536 | 27 | 65 000+ |
| PostgreSQL (pool) | 10 соединений | ~5–8 | ограничен по пропускной способности |
Практический потолок: 200–400 одновременно подключённых устройств (ограничен RAM, не лимитами BEAM).
Одновременных активных HTTP-запросов через туннели¶
Каждый проксированный запрос браузера создаёт короткоживущую цепочку: nginx → dixu_proxy → WS-событие → device_client → local server → обратно. Узкое место — 1 планировщик Erlang:
- При I/O-dominated нагрузке (запросы быстро уходят на устройство и ждут ответа) планировщик почти свободен — могут одновременно находиться в полёте несколько сотен запросов.
- При CPU-dominated нагрузке (большие тела, частое кодирование/декодирование base64, роутинг сотен сообщений одновременно) — деградация начинается при ~50–100 активных запросах.
Практическая оценка: 50–150 одновременных запросов без заметной задержки, при условии что каждое устройство отвечает быстро (< 200ms).
Одновременных пользователей браузера¶
| Слой | Лимит |
|---|---|
| nginx (TLS соединения) | 1024 |
| modulauth (UI-страницы) | несколько сотен (WebFlux неблокирующий) |
| dixu_proxy (проксирование) | 50–150 активных запросов (однопоточный планировщик) |
Практический лимит: ~100–300 одновременных пользователей, которые активно проксируют трафик через туннели. Пассивных пользователей (кто смотрит профиль, визитку, каталог — всё идёт через modulauth, минуя dixu_proxy) — значительно больше, до 500+.
TCP-туннели (SSH/RDP/VNC/PostgreSQL/MySQL/Redis/MongoDB)¶
Каждое TCP-соединение: 1 Erlang-процесс для relay + 1 порт Erlang + ~50 KB RAM.
| Ресурс | Лимит | Оценка запаса |
|---|---|---|
| Erlang-порты | 65 536 | ~65 000 TCP-соединений |
| RAM | ~300–400 MB свободно | ~6 000–8 000 соединений (50 KB каждое) |
| Планировщик | 1 | деградация при ~500+ активных TCP relay |
Практический потолок TCP: ~500–1000 одновременных TCP-соединений.
Текущие узкие места (по приоритету)¶
1. Единственный CPU / один BEAM-планировщик (критично)¶
Самое жёсткое ограничение. Erlang отлично масштабируется горизонтально (дополнительные ноды), но вертикально ограничен числом ядер. При нагрузке > 70% CPU latency растёт нелинейно.
Порог тревоги: load average > 0.7 (70% одного ядра).
Решение при росте: апгрейд VPS до 2–4 CPU — BEAM немедленно задействует все ядра (schedulers_online = число ядер).
2. PostgreSQL max_connections = 100 (среднесрочно)¶
При появлении новых компонентов или росте аналитической нагрузки можно упереться. dixu_proxy pool=10 + modulauth pool ≈ 20 = 30 занятых → 70 свободных. Запас умеренный.
Решение при необходимости: добавить PgBouncer (connection pooler) или поднять max_connections до 200–300 в postgres секции docker-compose (command: postgres -c max_connections=200).
3. RAM (1.9 GB) — умеренный запас¶
~900 MB занято, ~631 MB свободно + 835 MB buff/cache (ОС отдаст при необходимости). screenshotter занимает 101 MB при практически нулевой активности (статический Chromium-процесс). При росте числа устройств dixu_proxy потребует больше памяти.
Порог тревоги: RAM available < 200 MB при нагрузке. Решение: апгрейд до 4 GB RAM (dixu_proxy + modulauth вместе могут использовать 1–1.5 GB при нагрузке).
4. nginx worker_connections = 1024 (долгосрочно)¶
При 1 worker ограничение 1024 одновременных соединений. При реальном трафике это включает keep-alive соединения браузеров — реальная параллельная обработка меньше.
Решение: worker_connections 4096 или worker_processes 2 (если будет > 1 CPU).
Итоговые цифры¶
| Показатель | Текущий потолок | Узкое место |
|---|---|---|
| Подключённых устройств одновременно | 200–400 | RAM dixu_proxy |
| Активных HTTP-запросов через туннель | 50–150 | 1 CPU / BEAM-планировщик |
| Одновременных пользователей (браузер) | 100–300 | 1 CPU / nginx 1024 |
| TCP-соединений (SSH/RDP/VNC/БД) | 500–1000 | BEAM-планировщик |
| PostgreSQL соединений | 100 max | max_connections=100 |
Текущий сервер рассчитан на десятки пользователей с несколькими активными устройствами — и справляется с этим с очень низкой нагрузкой (load avg 0.03). Для роста до сотен устройств / тысяч пользователей потребуется апгрейд VPS до минимум 2 CPU + 4 GB RAM.
Рекомендации при масштабировании¶
| Целевой масштаб | Что сделать |
|---|---|
| 10–50 устройств, ~500 пользователей/сутки | Ничего — текущий VPS справляется |
| 50–200 устройств, ~2000 пользователей/сутки | Апгрейд до 2 CPU + 4 GB RAM; worker_connections 4096 в nginx |
| 200–500 устройств, ~10 000 пользователей/сутки | 4 CPU + 8 GB RAM; PgBouncer; разнести dixu_proxy и modulauth на отдельные инстансы |
| 500+ устройств / высоконагруженные туннели | Кластер Erlang (multi-node BEAM) + несколько nixu_proxy нод; балансировщик перед nginx |