This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
# 2026-07-11 — Диагностика WebSocket 51s stall: итог
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
|
||||||
|
WebSocket-загрузка файлов через ingress (Flask + flask-sock + Werkzeug).
|
||||||
|
Файлы >1 MB: ~20-30% соединений быстрые (~0.5с), ~70-80% — 51 секунда.
|
||||||
|
Задержка **не зависит от размера файла** (2MB и 4MB — одинаково 51с).
|
||||||
|
|
||||||
|
## Что проверено (полный список)
|
||||||
|
|
||||||
|
### Код приложения
|
||||||
|
| Изменение | Результат |
|
||||||
|
|---|---|
|
||||||
|
| Baseline (без flow control) | ~20% fast |
|
||||||
|
| `bufferedAmount` flow control | ~20% (затык на 20% вместо 90%) |
|
||||||
|
| Server-side ACK (чанк→ack→след) | 0% (сломано полностью) |
|
||||||
|
| Возврат к baseline | ~20% fast |
|
||||||
|
|
||||||
|
### Платформа (Shturval + Cilium)
|
||||||
|
| Изменение | Результат |
|
||||||
|
|---|---|
|
||||||
|
| nodeSelector (под = нода с ingress) | ~20% fast |
|
||||||
|
| Scale ingress до 4 (на всех нодах) | ~20% fast |
|
||||||
|
| hostNetwork на python поде | ~20% fast |
|
||||||
|
| keepalive=0 к upstream | ~30% fast |
|
||||||
|
|
||||||
|
### Конфигурация nginx (ingress)
|
||||||
|
- `proxy_buffering off`, `proxy_request_buffering off`
|
||||||
|
- `proxy_send_timeout 600s`, `proxy_read_timeout 600s`
|
||||||
|
- ModSecurity OWASP CRS 4.10 (DetectionOnly)
|
||||||
|
- `client_body_buffer_size 2m`
|
||||||
|
- Без `limit_rate`, без `limit_req`
|
||||||
|
|
||||||
|
### Сеть
|
||||||
|
- Cilium Geneve tunnel mode, kube-proxy replacement
|
||||||
|
- kube-vip ARP mode на всех 4 нодах
|
||||||
|
- `enable-host-legacy-routing: true`
|
||||||
|
|
||||||
|
## Ключевой тест
|
||||||
|
|
||||||
|
5×2MB через VIP с моей машины (CLI, не браузер):
|
||||||
|
|
||||||
|
```
|
||||||
|
#0: total=52.2s sent=52.0s resp=0.2s
|
||||||
|
#1: total=0.7s sent=0.6s resp=0.1s ← FAST
|
||||||
|
#2: total=50.8s sent=50.6s resp=0.2s
|
||||||
|
#3: total=52.3s sent=52.1s resp=0.2s
|
||||||
|
#4: total=51.9s sent=51.8s resp=0.1s
|
||||||
|
```
|
||||||
|
|
||||||
|
Задержка в фазе `send()` — клиент блокируется при отправке данных.
|
||||||
|
TCP backpressure: где-то в цепочке буфер переполняется и не дрейнуется.
|
||||||
|
|
||||||
|
## Вывод
|
||||||
|
|
||||||
|
**Проблема на стороне платформы (Shturval/nginx-ingress/Cilium), не приложения.**
|
||||||
|
|
||||||
|
51-секундная задержка константна, не зависит от:
|
||||||
|
- Размера файла
|
||||||
|
- Node placement
|
||||||
|
- Cilium Geneve vs hostNetwork
|
||||||
|
- Количества ingress реплик
|
||||||
|
- keepalive к upstream
|
||||||
|
|
||||||
|
Единственный стабильный метод: HTTP POST (но Werkzeug рвёт соединение в 30-50% случаев).
|
||||||
|
|
||||||
|
## Текущее состояние
|
||||||
|
|
||||||
|
- Код: baseline v1.0.18 (без flow control, без ACK)
|
||||||
|
- Кластер: все изменения откачены
|
||||||
|
- WebSocket работает, но с 51-секундной паузой в 70-80% случаев
|
||||||
+1
-1
@@ -7,7 +7,7 @@ from flask_sock import Sock
|
|||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
sock = Sock(app)
|
sock = Sock(app)
|
||||||
|
|
||||||
VERSION = '1.0.17'
|
VERSION = '1.0.18'
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
|
|||||||
Reference in New Issue
Block a user