docs: README — project overview, problem, fix, usage
Deploy loadtest / validate (push) Has been cancelled
Deploy loadtest / validate (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,77 @@
|
|||||||
|
# loadtest — загрузка файлов через Managed Flask (Shturval)
|
||||||
|
|
||||||
|
Тестовый проект для проверки Managed Flask на платформе Shturval 2.12.1.
|
||||||
|
Задача: принять загрузку файлов 3-5 MB через веб-интерфейс стабильно и быстро.
|
||||||
|
|
||||||
|
## Как работает
|
||||||
|
|
||||||
|
- **Фронтенд:** HTML + vanilla JS, выбор файлов, прогресс-бар, drag-and-drop
|
||||||
|
- **Бэкенд:** Flask 3.1 + flask-sock (WebSocket) + Gunicorn (gevent worker)
|
||||||
|
- **Загрузка:** WebSocket, 64KB чанки, один connection на все файлы
|
||||||
|
- **Деплой:** git push → Shturval auto-deploy
|
||||||
|
|
||||||
|
## Проблема: 51-секундный TCP stall
|
||||||
|
|
||||||
|
### Симптом
|
||||||
|
Файл 3.7 MB — 90% мгновенно, затем пауза ровно 51 секунда. В ~80% соединений.
|
||||||
|
|
||||||
|
### Корень
|
||||||
|
`externalTrafficPolicy: Cluster` (дефолт) на LoadBalancer-сервисе `shturval-ingress-controller-controller`. Kube-vip в ARP-режиме форвардил трафик на ноды без локального ingress-пода → cross-node форвардинг через Geneve → TCP zero window oscillation → 51 секунда.
|
||||||
|
|
||||||
|
### Исправление (платформа)
|
||||||
|
```bash
|
||||||
|
kubectl patch svc -n ingress shturval-ingress-controller-controller \
|
||||||
|
-p '{"spec":{"externalTrafficPolicy":"Local"}}'
|
||||||
|
|
||||||
|
kubectl scale deploy -n ingress shturval-ingress-controller-controller --replicas=4
|
||||||
|
```
|
||||||
|
|
||||||
|
С `Local` трафик идёт только на ноды с локальными ingress-подами. Cross-node форвардинг исключён.
|
||||||
|
|
||||||
|
### Что НЕ помогло
|
||||||
|
- Flow control на клиенте (`bufferedAmount`, ACK)
|
||||||
|
- Gunicorn вместо Werkzeug
|
||||||
|
- nginx keepalive, buffering, таймауты
|
||||||
|
- nodeSelector, hostNetwork
|
||||||
|
- HTTP POST вместо WebSocket
|
||||||
|
|
||||||
|
Внутри кластера всё работало мгновенно — проблема была только при проходе через VIP извне.
|
||||||
|
|
||||||
|
## Как юзать загрузку
|
||||||
|
|
||||||
|
1. Открыть https://loadtest.pythonk8s.dev.nubes.ru/
|
||||||
|
2. Нажать «Выбрать файлы» или перетащить файлы в зону загрузки
|
||||||
|
3. Нажать «Загрузить»
|
||||||
|
4. Прогресс-бар показывает реальный прогресс
|
||||||
|
5. После загрузки — ✓ с временем и скоростью
|
||||||
|
|
||||||
|
Поддерживается множественная загрузка (несколько файлов подряд через один WebSocket).
|
||||||
|
|
||||||
|
## Структура проекта
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── Dockerfile # Gunicorn CMD (не используется Shturval)
|
||||||
|
├── requirements.txt # flask, gunicorn, gevent, flask-sock
|
||||||
|
├── site/
|
||||||
|
│ ├── app.py # Flask: /, /health, /upload (HTTP), /ws-upload (WS)
|
||||||
|
│ ├── static/
|
||||||
|
│ │ └── app.js # Клиент: выбор файлов, WebSocket загрузка
|
||||||
|
│ └── templates/
|
||||||
|
│ └── index.html # UI
|
||||||
|
└── History/ # Полная история расследования
|
||||||
|
├── 2026-07-11-fix-externalTrafficPolicy.md # Финальный фикс
|
||||||
|
├── 2026-07-11-sonnet-review.md # Отчёт для ревью
|
||||||
|
└── 2026-07-11-review-response.md # Рецензия и выводы
|
||||||
|
```
|
||||||
|
|
||||||
|
## Выводы для других проектов на Shturval
|
||||||
|
|
||||||
|
1. **Managed Flask может принимать большие файлы** — после фикса платформы
|
||||||
|
2. **Всегда проверять «работает ли изнутри кластера»** — это изолирует платформу от кода
|
||||||
|
3. **WebSocket через managed ingress работает** — с правильным `externalTrafficPolicy`
|
||||||
|
4. **Если платформа не чинится** — вынести загрузку на ВМ с родным nginx (как в проекте `contracts`)
|
||||||
|
|
||||||
|
## Версия
|
||||||
|
|
||||||
|
Текущая: **1.0.25** (baseline WebSocket + Gunicorn gevent)
|
||||||
Reference in New Issue
Block a user