Перейти к содержанию

Деплой, мониторинг и нагрузочное тестирование

Деплой

Exchange Engine

Расположение файлов: /exchange/deployment/ (23 файла)

Docker-образы

Используется multi-stage build: golang:1.25-alpinealpine:3.20. Dockerfile находится в корне репозитория.

Build args:

Аргумент Описание
APP_NAME Имя собираемого бинарника
VERSION Версия образа (используется в метаданных)

Тегирование: формат YYYYMMDD-COMMITHASH, например 20260306-0f1b10b

Собираемые образы (12 штук)

Группа Образы
Основные admin, api, engine
Topup Scan topupscan-btc, topupscan-evm, topupscan-tron, topupscan-processor, topupscan-aml-poller, topupscan-elliptic-check, topupscan-refund-processor
TX Processor txprocessor-btc, txprocessor-evm, txprocessor-tron
Hot Manager hotmanager-btc, hotmanager-evm, hotmanager-tron

Build-инструменты

  • Skaffold — конфигурация в skaffold.yaml, используется для локальной разработки и сборки
  • Makefile — основные цели:
make all      # сборка + lint + тесты
make build    # только сборка образов
make lint     # golangci-lint
make test-go  # запуск Go-тестов

Secrets

Секреты управляются через Sealed Secrets — зашифрованные манифесты хранятся в /deployment/sealed-secrets/.

CI/CD

GitHub Actions (.github/workflows/tests.yml) выполняет при каждом PR и пуше:

  • Go unit-тесты
  • golangci-lint — статический анализ кода
  • buf — lint и breaking-change проверки для Protobuf-схем

Kubernetes-ресурсы

resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1000m
    memory: 1Gi

Метрики: каждый pod экспортирует Prometheus-метрики на порту 8081 по пути /metrics.


Univex Monorepo

Расположение: у каждого микросервиса свой подкаталог deployments/; общие продакшн-манифесты — в /prod-deployments/ (41 файл).

Docker-образы

Используется multi-stage build: golang:1.23scratch (минимальный финальный образ). Dockerfile расположен внутри каждого микросервиса.

Kubernetes namespace: prod

Kubernetes-ресурсы

Параметр Requests Limits
CPU 100–200m 300m–1000m
Memory 256–512Mi 512Mi–2Gi

Диапазон зависит от нагрузки конкретного микросервиса.

Миграции БД

Для каждой базы данных запускается отдельный Kubernetes Job (migrator-job.yaml) с настройкой backoffLimit: 3. Миграция выполняется до старта основного Deployment.

Temporal Workers

Workers Temporal вынесены в отдельные Deployment-ресурсы и масштабируются независимо от HTTP/gRPC-сервисов.


Базы данных (продакшн)

Docker Compose файл: /univex/prod-deployments/docker-compose-prod.yml

В продакшне развёрнуто 10 PostgreSQL баз данных, каждая с выделенным PgBouncer в режиме transaction pooling (max 100 connections на пул).

База данных PgBouncer-порт
univex-id 6100
exchange 6101
sms 6102
email 6103
sumsub 6104
p2p 6105
bot 6107
casbin 6108
exchange_int 6109
ledger 6110

Ingress-паттерн

Все HTTP/WebSocket-сервисы используют единый шаблон ingress:

  • Ingress class: nginx
  • TLS: cert-manager с cluster-issuer letsencrypt (автоматическое получение сертификатов Let's Encrypt)
  • CORS: настраивается через аннотацию configuration-snippet с more_set_headers

WebSocket выносится в отдельный ingress с увеличенными таймаутами:

nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-buffering: "off"

Мониторинг (Grafana + Prometheus)

Расположение всех манифестов: /univex/monitoring/

Prometheus

Файл Назначение
prometheus-config.yaml Основная конфигурация: scrape jobs, targets
prometheus-deployment.yaml Kubernetes Deployment
prometheus-ingress.yaml Внешний доступ к UI
prometheus-rbac.yaml ServiceAccount + ClusterRole для service discovery

Scrape interval: 15 секунд

Prometheus автоматически собирает метрики со всех микросервисов:

  • Univex — порт метрик 8000
  • Exchange Engine — порт метрик 8081

Grafana

Файл Назначение
grafana-deployment.yaml Dev-окружение
grafana-prod-deployment.yaml Продакшн
grafana-ingress.yaml / grafana-prod-ingress.yaml Ingress для dev / prod
grafana-datasource.yaml Datasource: Prometheus
grafana-dashboard-provisioning.yaml Автоматическая загрузка дашбордов

Дашборды (16 штук)

Все дашборды хранятся как Kubernetes ConfigMap и подгружаются через provisioning при старте Grafana.

Дашборд Файл Ключевые метрики
Overview grafana-dashboard-overview.yaml Все сервисы: RPS, SLA, ошибки
Gateway grafana-dashboard-gateway.yaml univex_grpc, ledger_rpc, p2p_rpc
Admin Gateway grafana-dashboard-admin-gateway.yaml Admin gateway запросы
UnivexID grafana-dashboard-univex-id.yaml id_service RPC-метрики
Ledger grafana-dashboard-ledger.yaml ledger_rpc: запросы/мин, SLA%, ошибки
P2P grafana-dashboard-p2p.yaml p2p_rpc: запросы, длительность, ошибки
Exchange grafana-dashboard-exchange.yaml exchange_rpc, grpc_server
Exchange Integration grafana-dashboard-exchange-integration.yaml exchange_integration_rpc
Trades Aggregator grafana-dashboard-trades-aggregator.yaml trades_rpc
Email grafana-dashboard-email.yaml email_rpc
SMS Gate grafana-dashboard-sms-gate.yaml sms_rpc
Sumsub grafana-dashboard-sumsub-integration.yaml sumsub_rpc
Business grafana-dashboard-business.yaml Бизнес-метрики Univex
Exchange Business grafana-business-dashboard.yaml Exchange бизнес-метрики

Отслеживаемые метрики

На каждом дашборде отображаются:

  • RPC requests/min — количество запросов в минуту
  • Success rate (SLA%) — доля успешных ответов
  • Error rate — доля ошибочных ответов (4xx, 5xx, gRPC errors)
  • Latency percentiles — p50, p95, p99

Нагрузочное тестирование

Exchange Engine

ghz (gRPC benchmarking)

Файлы конфигураций: /exchange/deployment/loadtest-*.yaml (5 конфигураций)
Docker-образ: ghcr.io/bojand/ghz:latest
Тестируемый RPC: EngineService/AddOrder

Сценарий Описание Конкурентность Длительность
S3 local Локальный стакан 5 60s
S3 remote Удалённый стакан 5 60s
S5 BID Только BID-ордера 10 60s
S5 ASK Только ASK-ордера 10 60s
S5 prefill Prefill 30 000 ордеров + смешанная нагрузка 20 60s

cmd/bench (кастомный Go-инструмент)

Утилита находится в cmd/bench и позволяет гибко настраивать нагрузку:

./bench \
  -addr 127.0.0.1:1337 \
  -account-id <UUID> \
  -c 10 \
  -d 10s \
  -ticker BTCUSDT
Флаг Описание
-addr Адрес gRPC-сервера (TCP)
-unix Путь к Unix-сокету (альтернатива TCP)
-account-id UUID торгового аккаунта
-c Конкурентность (количество горутин)
-d Длительность теста
-ticker Торговая пара (например BTCUSDT)
-seed Сид для воспроизводимой генерации ордеров

Результат сравнения транспортов:

Транспорт RPS Latency
TCP базовый базовый
Unix socket +24% RPS −19% latency

Unix-сокет даёт существенный прирост производительности при локальном деплое (engine + клиент на одном узле).


Univex — Yandex.Tank

Phantom (GET-запросы)

Файл: /univex/load-testing/tank-pod.yaml

Target: gateway.<namespace>.svc.cluster.local:80
Instances: 3000
Timeout: 6s
Профиль нагрузки: line(1, 500, 60s) → const(500, 240s)
Итого: ~20 минут
Эндпоинтов: 29 GET-маршрутов

BFG (мутирующие операции)

Файл: /univex/load-testing/tank-bfg.yaml
Python-скрипт: load_script.py

Instances: 50
Профиль нагрузки: line(1, 70, 15s) → const(70, 15s)
Итого: ~10 минут

Тестируемые сценарии:

  • Payment methods — CRUD-операции
  • Blacklist — управление списком
  • Advertisements — создание и удаление объявлений

Autostop-условия

Тест автоматически останавливается при:

Условие Порог Окно
HTTP 5xx > 10% 30 сек
Сетевые ошибки > 25% 30 сек
Средняя задержка > 5 сек 30 сек

Запуск

# Phantom
kubectl apply -f tank-pod.yaml -n prod

# BFG
kubectl create configmap tank-bfg-script \
  --from-file=load_script.py -n prod
kubectl create configmap tank-bfg-ammo \
  --from-file=ammo.txt -n prod
kubectl apply -f tank-bfg.yaml -n prod

Результаты нагрузочного тестирования (4 марта 2026)

Метрика Значение
Всего запросов 541 148
Целевой RPS 500
Ошибок 0
Avg latency 11.6 мс
p95 latency 33 мс
p99 latency 47 мс
Оценка DAU ~1.2–1.4 млн пользователей