Files
loadtest/History/2026-07-10-upload-investigation.md
T
2026-07-10 21:19:31 +04:00

98 lines
5.1 KiB
Markdown

# 2026-07-10 — Полное расследование: почему режутся файлы при загрузке
## Симптом
Загрузка файлов > 64KB через веб-интерфейс loadtest обрывается. Даже чанки не проходят.
## Диагностика
### Тесты
| Тест | Результат |
|------|-----------|
| Изнутри пода (Flask, 100KB base64) | ✅ 102400 байт, 4ms |
| Снаружи (curl, 136KB URL-encoded POST) | ❌ 408 Timeout / Connection reset |
| Снаружи (Python urllib, 136KB POST) | ❌ RemoteDisconnected |
| Маленький POST (12 байт) | ✅ |
### Инфраструктура
```
Клиент → [прокси/LB] → nginx ingress (ModSecurity) → Flask dev-сервер (не Gunicorn!)
```
- Платформа: Shturval (managed Kubernetes)
- Сервис: `loadtest.pythonk8s.dev.nubes.ru`, IP `185.247.187.151` (NUBES LLC)
- Namespace: `9039a501-df2c-4b85-b049-9cd4f77e6ac0`
- Deployment: `pythonk8s`
- Запуск: `python app.py` (Flask dev-сервер, НЕ Gunicorn)
### ModSecurity в nginx ingress
```
SecRequestBodyLimit 13107200 # 12.5 MB — общий лимит
SecRequestBodyNoFilesLimit 131072 # 128 KB — лимит для НЕ-файловых полей
SecRuleEngine DetectionOnly # только логирует, не блокирует
```
Базовая строка 136KB отправляется как URL-encoded form → попадает под `NoFilesLimit`.
### Ingress-логи
- Маленькие POST (146 байт) → 200 OK
- Большие POST (49-65KB) → 408 Timeout через 10 секунд
- `ingress_request_length` показывает 49-65KB при отправленных 136KB → тело обрезается ДО ingress (прокси/LB)
## Предыдущий опыт (contracts)
Из `/home/naeel/nubes/contracts/History/`:
### `session-07-chunks.md` (v1.15-1.18)
- Чанки 50KB FormData → только первый доходит
- Чанки в PostgreSQL → то же самое
- 7 отдельных `psycopg2.connect` на сборку → медленно → таймаут Ingress
### `session-08-upload-saga.md` (v1.12-1.26)
- 26 версий до рабочей загрузки
- FormData/multipart → ❌
- base64 JSON → ❌
- v1.26: `original_bytes DROP NOT NULL` + `original_b64 TEXT` → ✓ РАБОТАЛО
- Потом регресс на v1.27+
### `upload-analysis-v40.md` (v1.40)
- `request.get_data(as_text=True)` + raw regex (без JSON, без b64decode, без БД) → всё равно HTTP 000
- Redis `rpush()` под подозрением
- curl: 100KB — 2/5 HTTP 000, 3/5 HTTP 200 (случайно)
### `connection-reset-analysis.md` (v1.21)
- HTTP 000 случайно, не зависит от размера
- Health check (GET) всегда 200
- Прямой /test (JSON → БД) всегда работает
### `sonnet-upload-from-scratch.md` — ИТОГ
> **"64KB — жёсткий предел платформы"**
> 43 версии. FormData, JSON/base64, чанки, Redis, retry — ничего не помогло.
## Корневая причина
Платформа pythonk8s (Shturval) имеет **непреодолимый предел ~64KB** на тело POST-запроса.
Это не баг приложения — это ограничение инфраструктуры:
- ModSecurity `SecRequestBodyNoFilesLimit` = 128KB
- Прокси/LB перед ingress обрезает тело ещё сильнее (до ~50-65KB)
- Ingress таймаутит через 10 секунд
Ни base64, ни JSON, ни чанки не обходят этот предел.
## Ложная правка
- `Dockerfile`: добавлены `--limit-request-field_size 0 --limit-request-body 0`**бесполезно**, т.к. Gunicorn не используется
- `site/app.py`: версия 1.0.4 → 1.0.5 — задеплоено, но проблему не решает
## Что дальше
Для loadtest как инструмента замера скорости загрузки этот предел фатален.
Нужно решать на уровне платформы:
1. Увеличить `SecRequestBodyNoFilesLimit` в ModSecurity
2. Убрать/настроить прокси/LB перед ingress
3. Либо перенести сервис на другую платформу без этих ограничений
## Источники
- `/home/naeel/nubes/contracts/History/sessions/session-07-chunks.md`
- `/home/naeel/nubes/contracts/History/sessions/session-08-upload-saga.md`
- `/home/naeel/nubes/contracts/History/features/upload-analysis-v40.md`
- `/home/naeel/nubes/contracts/History/features/upload-analysis-v41.md`
- `/home/naeel/nubes/contracts/History/features/connection-reset-analysis.md`
- `/home/naeel/nubes/contracts/History/features/chunk-analysis-request.md`
- `/home/naeel/nubes/contracts/History/llm-analysis/sonnet-upload-from-scratch.md`
- `/home/naeel/nubes/contracts/History/llm-analysis/sonnet-appjs-analysis.md`