Files
SQS-service/doc/progress.md
T

15 KiB
Raw Blame History

SQS-service Progress

Версия v0.1.x

v0.1.24 (2026-04-12) — Prometheus metrics + Victoria Metrics integration

  • ✅ Новый пакет app/metrics/ — Prometheus counters, histograms, gauges
  • ✅ Endpoint /metrics в формате Prometheus (promhttp.Handler)
  • ✅ Метрики: sqs_requests_total, sqs_request_bytes_total, sqs_request_duration_seconds, sqs_errors_total, sqs_queues_count, sqs_messages_count
  • ✅ Labels: tenant, operation — для фильтрации в Grafana
  • ✅ Gauge updater: пересчёт очередей/сообщений per tenant каждые 15s
  • ✅ VMServiceScrape создан в namespace shared-sqs — VMAgent скрейпит каждые 30s
  • ✅ Go 1.23 в Dockerfile (требование prometheus client)
  • ✅ Docker image naeel/shared-sqs:v0.1.24 — собран и запушен
  • ✅ Live deploy: все метрики отдаются, quick_test 31/31 PASS

Стресс-тест с нуля (2026-04-12)

  • ✅ Namespace shared-sqs удалён и пересоздан с нуля
  • ✅ Обнаружен и исправлен сменившийся пароль Redis (managed сервис обновил credentials)
  • ✅ Обнаружено и исправлено: server-snippet аннотация заблокирована nginx ingress controller как "risky" — удалена из ingress.yaml
  • ✅ Pod kill → восстановление за ~3 секунды, auto-reconnect Redis + PG
  • ✅ Quick test: 31/31 PASS (приватная репа), 7/7 + 18/18 PASS (публичная репа)
  • ✅ Нагрузка: 5 тенантов, 15 очередей, 120 сообщений (90 single + 30 batch), 90 received
  • ✅ Billing PG: 176 записей, все 17 типов операций
  • ✅ Prometheus /metrics: все sqs_* метрики заполнены реальными данными по тенантам

v0.1.23 (2026-04-12) — billing: учёт SQS-операций в PostgreSQL

  • ✅ Новый пакет app/billing/ — подключение к PG, auto-migrate, async запись usage
  • ✅ Интеграция в actionHandler — каждая успешная SQS-операция записывается
  • ✅ Опциональность: если BILLING_PG_HOST не задан — billing выключен, SQS работает как раньше
  • ✅ Helm chart: секция billing: в values.yaml, secret-billing.yaml, env в deployment.yaml
  • ✅ Таблица sqs_usage_records: tenant_id, operation, queue_name, msg_count, msg_bytes, recorded_at
  • ✅ Docker image naeel/shared-sqs:v0.1.23 — собран и задеплоен с PG credentials
  • ✅ Live: billing данные пишутся в PostgreSQL (17 типов операций за тест)

v0.1.22 (2026-04-12) — demo UI showcase mode deployed

  • ✅ Demo UI token поддержан сервером: demo-ui-shared-sqs-ngcloud-2026
  • ✅ Реальный JWT login сохранён без изменений
  • ✅ UI API ограничен текущим tenant-ом, без обзора всех tenant-ов
  • ✅ Собран и запушен image naeel/shared-sqs:v0.1.22
  • ✅ Live deployment обновлён до naeel/shared-sqs:v0.1.22
  • ✅ Live smoke validation: bash tests/quick_test.sh → 31/31 PASS
  • ✅ Demo token на live /ui/api/auth возвращает demo tenant t-demo-shared-sqs-ngcloud

v0.1.22-dev (2026-04-12) — demo UI login + UI tenant scoping

  • ✅ Добавлен публичный UI demo token: demo-ui-shared-sqs-ngcloud-2026
  • ✅ Demo token маппится на уже сидированный demo tenant t-demo-shared-sqs-ngcloud
  • ✅ UI API больше не показывает чужие tenant-ы: GET /ui/api/tenants возвращает только текущий tenant
  • ✅ UI health для авторизованного пользователя считает только его очереди и сообщения
  • ✅ Создание и удаление tenant-а через UI отключены, чтобы demo/login-console не выглядела как admin panel
  • ✅ Узкая валидация: go test ./app/admin PASS
  • ✅ Публичный showcase README синхронизирован с новым demo UI token

v0.1.21 (2026-04-11) — Redis schema v2 + per-message persistence

  • ✅ Redis schema v2: metadata в HASH ssq:queues, сообщения в отдельных HASH ssq:msg:{queueKey}
  • ✅ Per-message persistence: каждая операция (send/receive/delete/visibility) пишет только затронутое сообщение
  • ✅ Migration v1→v2: автоматическая миграция при старте (59 очередей мигрировано)
  • ✅ quick_test: 31/31 PASS
  • ✅ shared_sqs_test: 28/28 PASS
  • Docker image: naeel/shared-sqs:v0.1.21

Производительность v0.1.21 (benchmark)

Размер shared-sqs Yandex MQ Сравнение
1KB ~800ms ~700ms Паритет
10KB 880-965ms 916-996ms Быстрее
32KB 883-939ms 905-948ms Быстрее

Проблема 65KB+ payload (расследование 2026-04-11)

Root cause: botocore (AWS SDK) + urllib3 2.0 + TLS record boundary.

  • urllib3 2.0 отправляет headers и body двумя отдельными send() вызовами
  • botocore убирает TCP_NODELAY (алгоритм Nagle включён)
  • Последняя TLS-запись (~16KB) застревает из-за Nagle + delayed ACK
  • nginx client_body_timeout срабатывает → HTTP 408

Попытка фикса nginx:

  • ConfigMap: client-body-timeout: "120", client-body-buffer-size: "2m" — применилось
  • Аннотация proxy-request-buffering: "off" — НЕ подхватилась shturval controller
  • pip boto3 (Python 3.12): исправлено (84ms → 13ms) ✅
  • AWS CLI (Python 3.14.3 bundled): всё ещё зависает (51843ms) ❌

Финальный вывод (2026-04-12):

  • проблема локализована на стороне platform ingress controller штурвала, а не в Go-сервисе shared-sqs;
  • ingress приложения корректен, но controller выборочно применяет аннотации: proxy-body-size и client-body-buffer-size доходят до nginx.conf, а proxy-request-buffering остаётся on;
  • upstream ingress-nginx эту аннотацию поддерживает, значит это platform-specific limitation/bug;
  • hard-limit 32KB в код shared-sqs НЕ вводим;
  • 32KB остаётся практической рекомендацией для AWS CLI / botocore в текущей инфраструктуре.
  • внешние ссылки для повторного разбора сохранены в doc/thinking/2026-04-12.md, doc/errors/65kb-payload-timeout-2026-04-11.md и doc/decisions/message-size-limit-2026-04-11.md.

v0.1.19 (2026-04-11) ✅ — ПРЕДЫДУЩАЯ DEPLOYED

  • ✅ Валидация VisibilityTimeout (0–43200) в ReceiveMessage
  • ✅ Валидация WaitTimeSeconds (0–20) в ReceiveMessage
  • ✅ Пустой MessageBody → MissingParameter в SendMessage
  • ✅ quick_test: 31/31 ✅
  • ✅ hardcore_test: 114/116 ✅ (2 flaky — 100KB TLS, не баг сервера)
  • ✅ stress_test: 21/23 ✅ (2 flaky — сеть/nginx, не баг сервера)
  • Docker image: naeel/shared-sqs:v0.1.19
  • Helm: deployments/helm/shared-sqs/ appVersion v0.1.19

v0.1.18 (2026-04-11) ✅

  • ✅ 4 новые API команды: ChangeMessageVisibilityBatch, TagQueue, UntagQueue, ListQueueTags
  • ✅ Итого API: 17 команд (полная Yandex/AWS SQS совместимость)
  • ✅ security: fix critical/high auth, idor, races and persistence
  • ✅ security: address medium risks in jwt, redis ordering and body limit
  • ✅ perf: optimize receive long polling and finalize formatting cleanup

v0.1.15 (2026-04-10) ✅

  • ✅ JWT auth через nubes API (deck-api-test.ngcloud.ru)
  • ✅ Login page в UI (ввод токена → валидация → auto-provisioning tenant)
  • ✅ /ui/api/* защищены JWT middleware
  • ✅ TenantID совместим с sless namespace: sless-{SHA256(sub)[:8]}

v0.1.14 (2026-04-10) ✅

  • ✅ Фикс критического дедлока в create_queue.go
  • ✅ Фикс UI: m.sent → m.sent_at
  • ✅ Redis write-through persistence
  • ✅ TLS Ingress: qu.kube5s.ru

Security & Compatibility Wave (2026-04-10) ✅

  • ✅ SigV4 подпись, IDOR fix, map race fix, persistence sync
  • ✅ shared_sqs_test.sh PASS=28 FAIL=0

Стресс-тестирование (2026-04-11) ✅

Результаты stress_test.sh v2 (финальный прогон)

# Секция Результат Детали
1 Подготовка (тенанты, очереди) ✅ 3 тенанта, автогенерация AK/SK
2 Конкурентная отправка (10×20) ✅ 200/200 доставлено
3 Конкурентное чтение ✅ 200 прочитано, 200 удалено, 0 в очереди
4 Multi-tenant изоляция ✅ 0 чужих сообщений, 3×30=90 своих
5 Burst (50 одновременно) ✅ 50/50 доставлено
6 Kill pod + восстановление ✅ Данные из Redis — 100% recovery
7 Redis disconnect ✅ HTTP 200 из кеша, graceful degradation
8 Смешанная нагрузка (15s) ✅* send+recv+delete+attr, 1 flaky attr
9 Cleanup ✅ Тенанты и очереди удалены

Итого: 21/23 ✅, 2 ❌ (flaky сеть, не баги сервера)

Покрытие тестами

Тест Что проверяет Результат
quick_test.sh 17 SQS команд, smoke 31/31 ✅
hardcore_test.sh Edge cases, лимиты, ошибки 114/116 ✅
stress_test.sh Конкурентность, resilience, isolation 21/23 ✅
Всего 166/170 ✅ (97.6%)

Next Steps

  • Перед production без demo user удалить из кода demo UI token path, seeded demo tenant, demo credentials в README и все публичные demo-подсказки в UI
  • Если demo path нужен дольше, сначала вынести его под явный feature flag с default=off для production окружения
  • Per-queue locking (заменить глобальный мьютекс на per-queue sync.RWMutex)
  • DLQ (Dead Letter Queue) — maxReceiveCount → перемещение в DLQ
  • Rate limiting per tenant
  • Prometheus метрики (exporter)
  • Горизонтальное масштабирование (leader election или Redis-based state)
  • Long polling оптимизация (channel-based вместо 100ms polling)
  • Go unit tests (go test ./...)

v0.1.15 (2026-04-10) ✅

  • ✅ JWT auth через nubes API (deck-api-test.ngcloud.ru)
  • ✅ Login page в UI (ввод токена → валидация → auto-provisioning tenant)
  • ✅ Email пользователя в navbar
  • ✅ /ui/api/* защищены JWT middleware (больше не публичные)
  • ✅ TenantID совместим с sless namespace: sless-{SHA256(sub)[:8]}
  • ✅ Сессия в localStorage (token + email)
  • Docker build + deploy + E2E test

Known Limitations

  1. Глобальный мьютекс — SyncQueues.Lock() на весь сервис. При >50 rps — bottleneck. Стресс-тест подтвердил: работает корректно (нет deadlock/race), но сериализует все операции.
  2. Нет DLQ — сообщения после maxReceiveCount не перемещаются. Для production — must-have.
  3. Long Polling наивный — polling каждые 100ms. При 20 клиентах = 200 poll/sec на пустую очередь.
  4. Нет rate limiting — один тенант может degradировать сервис для остальных.
  5. Single pod — replicas > 1 не работает из-за глобального мьютекса (два пода = два state).
  6. Нет метрик — Prometheus exporter отсутствует.
  7. 100KB сообщения — 2/116 flaky в hardcore_test (TLS/nginx buffer, не баг сервера).

Architecture

SQS-service/
├── app/
│   ├── cmd/main.go              — точка входа
│   ├── models/model.go          — Queue, Message, Tenant структуры
│   ├── gosqs/*.go               — реализация SQS API операций
│   ├── admin/admin.go           — Admin API (Create/List/Get Tenant)
│   ├── tenant/tenant.go         — Multi-tenant изоляция
│   ├── auth/auth.go             — AWS Signature V4 верификация
│   ├── persistence/redis.go     — Redis adapter для persistence
│   ├── router/router.go         — HTTP маршруты
│   └── ui/index.html            — Web Console
├── deployments/k8s/             — Kubernetes манифесты
├── tests/                       — E2E тесты
└── doc/                         — Документация

Technology Stack

  • Language: Go 1.22
  • HTTP Server: Go std net/http
  • Auth: AWS Signature V4
  • Storage: Redis (write-through)
  • Container: Docker
  • Orchestration: Kubernetes
  • DNS: Ingress с TLS

Demo Credentials (read-only для тестирования)

Access Key: SSAK-demo-shared-sqs
Secret Key: demo-secret-key-shared-sqs-ngcloud-2026
Endpoint: https://qu.kube5s.ru

TODO перед production без demo-доступа:

  • удалить demo token path из app/admin/admin.go
  • выключить/удалить seeded demo tenant
  • удалить публичные demo credentials и demo token из пользовательской документации
  • убрать demo-подсказки из app/ui/index.html

Deployment

# Kubernetes
kubectl apply -k deployments/k8s/

# Docker (local)
docker run -p 9090:9090 naeel/shared-sqs:v0.1.14

Last updated: 2026-04-10