Files
SQS-service/doc/errors/65kb-payload-timeout-2026-04-11.md
T

7.2 KiB
Raw Blame History

Error Log: 65KB+ Payload Timeout — 2026-04-11

Update — 2026-04-12

После дополнительного расследования в кластере инцидент переклассифицирован.

Финальный статус

  • shared-sqs backend не является первичной причиной зависания;
  • проблема локализована на стороне platform ingress path;
  • конкретно: ingress controller штурвала не применяет nginx.ingress.kubernetes.io/proxy-request-buffering: "off", хотя upstream ingress-nginx эту аннотацию поддерживает;
  • часть других аннотаций при этом применяется корректно, значит речь не о полном игноре ingress-ресурса, а о selective handling/bug/platform override.

Дополнительные подтверждения

  1. Для host qu.kube5s.ru существует только один ingress — shared-sqs-ingress, значит это не конфликт нескольких ingress-объектов.
  2. В объекте ingress аннотация proxy-request-buffering: "off" присутствует.
  3. В итоговом nginx.conf для qu.kube5s.ru остаётся proxy_request_buffering on;.
  4. В шаблоне контроллера /etc/nginx/template/nginx.tmpl директива не захардкожена; там используется значение location.Proxy.RequestBuffering, то есть проблема происходит до фазы рендеринга финального location config.
  5. server-snippet/configuration-snippet нельзя считать рабочим обходным путём без platform-level изменений, так как snippet-аннотации контролируются allow-snippet-annotations, а по умолчанию этот режим отключён.

Операционный вывод

Это известное ограничение инфраструктуры, а не дефект бизнес-логики shared-sqs.

Итоговое решение

  • hard-limit 32KB в код shared-sqs не внедряется;
  • 32KB остаётся практической рекомендацией для AWS CLI/botocore-клиентов в текущей инфраструктуре;
  • приоритет дальнейших работ по этой теме переносится с shared-sqs на platform ingress controller.

Симптом

SendMessage с телом ≥64740 байт зависает на 10-52 секунды и возвращает ошибку (ConnectionClosedError / exit=254).

Воспроизведение:

# Генерим payload 65KB
python3 -c "print('A'*65536)" > /tmp/big.txt

# Отправляем через AWS CLI — зависает на ~52 секунды
aws --endpoint-url https://qu.kube5s.ru sqs send-message \
  --queue-url "https://qu.kube5s.ru/TENANT_ID/QUEUE_NAME" \
  --message-body "file:///tmp/big.txt"

Диагностика

1. Сервер — OK

Port-forward (обход nginx): 65KB за 831ms. Сервер не виноват.

2. nginx ingress — частично виноват

client_body_timeout: 10s — nginx закрывает соединение если тело не пришло за 10 секунд.

3. Root Cause — botocore + urllib3 2.0 + TLS + Nagle

urllib3 2.0 посылает headers и body двумя отдельными send():

send#1: len=774  (headers)
send#2: len=65629 (body)

botocore ставит socket_options=[] → убирает TCP_NODELAY → Nagle ON.

Body шифруется TLS в 4 записи по ~16KB. Первые 3 уходят, 4-я застревает из-за Nagle + delayed ACK deadlock.

nginx access.log:

POST status=408 req_len=49926 bytes_sent=0 time=10.001s

Получено 49926 байт = headers(774) + 3 × TLS(~16384). Не хватает ровно 1 TLS-записи.

4. Порог

Размер Время Статус
64000B 825ms
64720B 799ms
64740B 30806ms intermittent
65536B 51843ms всегда

5. Версии ПО

Компонент Версия
nginx ingress shturval-ingress-controller v1.12.6
AWS CLI v2.34.27
AWS CLI Python 3.14.3 (bundled)
System Python 3.12.3
System urllib3 2.0.7
System botocore 1.42.86

Что пробовали

Помогло частично:

  • ConfigMap client-body-timeout: "120" — pip boto3 (Python 3.12) стал работать (84ms → 13ms)
  • ConfigMap client-body-buffer-size: "2m" — применилось глобально

Не помогло:

  • Аннотация proxy-request-buffering: "off" — shturval controller не применяет
  • server-snippet: client_body_timeout 120s; — применилось но AWS CLI всё равно зависает
  • TCP_NODELAY patch через monkey-patch — нестабильно (1-й запрос fails)

Решение

Кодовый hard-limit не вводим.

Практическое правило эксплуатации:

  • для AWS CLI / botocore в текущей ingress-инфраструктуре безопасно ориентироваться на 32KB;
  • протокольный лимит SQS остаётся 256KB;
  • проблема 64KB+ описывается как platform ingress limitation.

См. решение.

Статус

Исследование завершено. Root cause локализован до platform ingress layer; изменение в коде shared-sqs не требуется.

Внешние ссылки

Для следующего захода в проблему использовать эти ссылки как стартовые:

Краткий смысл ссылок:

  • Штурвал: подтверждает, что Nginx Ingress Controller является частью platform stack;
  • ingress-nginx docs/source: подтверждают, что proxy-request-buffering — штатная поддерживаемая фича upstream, а значит текущее поведение похоже именно на platform-specific limitation/bug.