nginx termina la conexión después de 65k bytes

11

Tengo nginx configurado como front-end para una aplicación Python que se ejecuta bajo gunicorn, pero nginx está finalizando las conexiones después de que se hayan enviado aproximadamente 65k de datos.

Por ejemplo, tengo una vista que se ve así:

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

Pero cuando accedo a esa URL a través de nginx, solo obtengo 65283 bytes:

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

Tenga en cuenta que todo funciona como se espera al acceder directamente a gunicorn:

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

La configuración de nginx relevante:

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

Y nginx versión 1.7.0

Algunos otros hechos:

  • El número de bytes es consistente de solicitud a solicitud, pero varía según el contenido (lo noté por primera vez con un archivo PNG grande, que se cortó después de 65,372 bytes, no 65,283)
  • 110k bytes se envían correctamente (es decir, "x" * 110000devuelve todos los 110,000 bytes), pero 120k bytes no son
  • tcpdump sugiere que nginx está enviando un paquete RST a gunicorn: nginx enviando RST
David Wolever
fuente
Sería útil ver (a) cómo gunicorn está eligiendo enmarcar las respuestas de 110k a 120k bytes de tamaño, y (b) cómo nginx elige su encuadre para el mismo rango de tamaños de carga útil de muestra entre 110k y 120k bytes. Las tres formas en que HTTP puede enmarcar datos: proporcionar longitud de contenido; hacer codificación fragmentada; o no enmarque, excepto para prometer cerrar el zócalo cuando el cuerpo esté completo.
Brandon Rhodes
Se proporciona un encabezado de longitud de contenido. Permítanme volcar el paquete para ver qué está pasando entre los dos, de lo contrario ...
David Wolever
Hrm, muy raro. tcpdump sugiere que nginx está activando la conexión RST (ver edición). nginx también está usando HTTP / 1.0 y Connection: close. También he confirmado que el Content-Lengthencabezado es correcto.
David Wolever

Respuestas:

10

¡Bueno! Después de verificar dos veces los registros de nginx, este resultó ser el 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 alguna manera, los permisos para el proxy_tempdirectorio se desordenaron, lo que impidió que nginx lo almacenara correctamente.

David Wolever
fuente
1
Sí, acabo de resolver un problema como este, busqué en los registros de nginx, tenía una línea que contenía [crit] 6636#0: *16817 open() "/var/lib/nginx/proxy/7/03/0000000037" failed (13: Permission denied) while reading upstream, lo hice sudo chown -R www-data:www-data /var/lib/nginx/y se solucionó.
Epigene