5.1 KiB
5.1 KiB
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, IP185.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 как инструмента замера скорости загрузки этот предел фатален. Нужно решать на уровне платформы:
- Увеличить
SecRequestBodyNoFilesLimitв ModSecurity - Убрать/настроить прокси/LB перед ingress
- Либо перенести сервис на другую платформу без этих ограничений
Источники
/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