nginx разрывает соединение после 65 Кбайт

11

Я настроил nginx в качестве внешнего интерфейса для приложения Python, работающего под Gunicorn, но nginx завершает соединения после отправки около 65 КБ данных.

Например, у меня есть представление, которое выглядит так:

def debug_big_file(request):
    return HttpResponse("x" * 500000)

Но когда я получаю доступ к этому URL через nginx, я получаю только 65283 байта:

$ curl https://example.com/debug/big-file | wc
…
curl: (18) transfer closed with outstanding read data remaining
   0       1   65283

Обратите внимание, что при доступе к gunicorn все работает правильно:

$ curl http://localhost:1234/debug/big-file | wc
…
   0       1   500000

Соответствующий конфиг nginx:

location / {
    proxy_pass http://localhost:1234/;
    proxy_redirect off;
    proxy_headers_hash_bucket_size 96;
}

И nginx версия 1.7.0

Некоторые другие факты:

  • Количество байтов является постоянным от запроса к запросу, но оно варьируется в зависимости от содержимого (я впервые заметил это с большим файлом PNG, который был обрезан после 65 372 байтов, а не 65 283)
  • "x" * 110000110 Кбайт отправлено правильно (т.е. возвращает все 110 000 байт), но 120 Кбайт не
  • tcpdump предполагает, что nginx отправляет пакет RST на gunicorn: nginx отправляет RST
Дэвид Волевер
источник
Было бы полезно увидеть (а) как Gunicorn выбирает кадрирование ответов размером от 110 до 120 Кбайт, и (б) как nginx выбирает кадрирование для того же диапазона размеров выборки полезной нагрузки от 110 до 120 Кбайт. Три способа, которыми HTTP может формировать данные: обеспечить длину содержимого; делать кодирование по частям; или вообще не давать никакого обрамления, кроме обещания закрыть розетку, когда тело будет готово.
Брэндон Родс
Предоставляется заголовок длины содержимого. Позвольте мне сбросить пакет, чтобы увидеть, что происходит между
этими
Хм, очень странно. tcpdump предполагает, что nginx активно RST-соединение (см. редактирование). nginx также использует HTTP / 1.0 и Connection: close. Я также подтвердил, что Content-Lengthзаголовок правильный.
Дэвид Вулевер

Ответы:

10

Ладно! После двойной проверки журналов nginx, это оказалось проблемой:

2014/05/26 16:50:56 [crit] 31396#0: *11 open() "…/proxy_temp/2/00/0000000002" failed (13: Permission denied) while reading upstream, client: 1.2.3.4, server: _, request: "GET /debug/big-file HTTP/1.1", upstream: "http://127.0.0.1:1234/debug/big-file", host: "example.com"

В некотором proxy_tempроде запутались права доступа к каталогу, что не позволило nginx правильно буферизовать его.

Дэвид Волевер
источник
1
Да, я только что решил проблему, вот так, посмотрел в логах nginx, имел строку с содержанием [crit] 6636#0: *16817 open() "/var/lib/nginx/proxy/7/03/0000000037" failed (13: Permission denied) while reading upstream, сделал, sudo chown -R www-data:www-data /var/lib/nginx/и она была исправлена.
Эпиген