nginx termina a conexão após 65k bytes

11

Eu tenho o nginx configurado como um front-end para um aplicativo Python em execução no gunicorn, mas o nginx está encerrando as conexões após o envio de cerca de 65k de dados.

Por exemplo, eu tenho uma visão parecida com esta:

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

Mas quando eu acesso esse URL através do nginx, recebo apenas 65283 bytes:

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

Observe que tudo funciona como esperado ao acessar o gunicorn diretamente:

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

A configuração nginx relevante:

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

E nginx versão 1.7.0

Alguns outros fatos:

  • O número de bytes é consistente de solicitação para solicitação, mas varia de acordo com o conteúdo (notei pela primeira vez com um arquivo PNG grande, cortado após 65.372 bytes, e não 65.283)
  • 110k bytes são enviados corretamente (ou seja, "x" * 110000retorna todos os 110.000 bytes), mas 120k bytes não são
  • tcpdump sugere que o nginx está enviando um pacote RST ao gunicorn: nginx enviando RST
David Wolever
fonte
Seria útil ver (a) como o gunicorn está escolhendo enquadrar respostas de 110k a 120k bytes de tamanho e (b) como o nginx escolhe seu enquadramento para o mesmo intervalo de tamanhos de amostra de carga útil entre 110k e 120k bytes. As três maneiras pelas quais o HTTP pode enquadrar dados: fornecer comprimento do conteúdo; fazer codificação em pedaços; ou não dê nenhuma moldura, exceto prometer fechar o encaixe quando o corpo estiver completo.
Brandon Rhodes
Um cabeçalho de comprimento de conteúdo está sendo fornecido. Deixe-me pacote despejar para ver o que está acontecendo entre os dois caso contrário ...
David Wolever
Hum, muito estranho. O tcpdump sugere que o nginx está ativamente fazendo o RST da conexão (consulte editar). O nginx também está usando HTTP / 1.0 e Connection: close. Também confirmei que o Content-Lengthcabeçalho está correto.
David Wolever

Respostas:

10

OK! Após verificar novamente os logs do nginx, este foi o problema:

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"

De alguma forma, como as permissões para o proxy_tempdiretório foram alteradas, impedindo o nginx de armazenar em buffer corretamente.

David Wolever
fonte
1
Sim, eu apenas resolvi um problema como este, procurei nos logs do nginx, tinha uma linha contendo [crit] 6636#0: *16817 open() "/var/lib/nginx/proxy/7/03/0000000037" failed (13: Permission denied) while reading upstream, fez sudo chown -R www-data:www-data /var/lib/nginx/e foi corrigida.
Epigene 3/11