uwsgi + nginx + matraz: aguas arriba cerrado prematuramente

Creé un punto final en mi matraz que genera una hoja de cálculo a partir de una consulta de base de datos (db remota) y luego la envío como descarga en el navegador. Frasco no arroja ningún error. Uwsgi no se queja.

Pero cuando verifico el error.log de nginx veo un montón de

12/12/2014 05:06:24 [error] 14084 # 0: * 239436 conexión ascendente prematuramente cerrada en sentido ascendente mientras se lee el encabezado de respuesta desde arriba, cliente: 34.34.34.34, servidor: me.com, solicitud: “GET / descargar / exportar .csv HTTP / 1.1 “, en sentido ascendente:” uwsgi: //0.0.0.0: 5002 “, host:” me.com “, referencia:” https://me.com/download/export.csv ”

Despliegue el uwsgi como

uwsgi --socket 0.0.0.0:5002 --buffer-size=32768 --module server --callab app 

mi configuración nginx:

 server { listen 80; merge_slashes off; server_name me.com www.me.cpm; location / { try_files $uri @app; } location @app { include uwsgi_params; uwsgi_pass 0.0.0.0:5002; uwsgi_buffer_size 32k; uwsgi_buffers 8 32k; uwsgi_busy_buffers_size 32k; } } server { listen 443; merge_slashes off; server_name me.com www.me.com; location / { try_files $uri @app; } location @app { include uwsgi_params; uwsgi_pass 0.0.0.0:5002; uwsgi_buffer_size 32k; uwsgi_buffers 8 32k; uwsgi_busy_buffers_size 32k; } } 

¿Es este un problema de nginx o uwsgi, o ambos?

Cambie nginx.conf para incluir

 sendfile on; client_max_body_size 20M; keepalive_timeout 0; 

Consulte el ejemplo completo de uwsgi upstart en amazon linux.

En mi caso, el problema era que nginx estaba enviando una solicitud con el protocolo uwsgi mientras uwsgi escuchaba en ese puerto los paquetes http. Entonces, o tuve que cambiar la forma en que nginx se conecta con uwsgi o cambiar uwsgi para escuchar usando el protocolo uwsgi.

Reemplace uwsgi_pass 0.0.0.0:5002; con uwsgi_pass 127.0.0.1:5002; o mejor usar sockets unix.

Parece que muchas causas pueden estar detrás de este mensaje de error. Sé que está utilizando uwsgi_pass , pero para aquellos que tienen el problema en solicitudes largas al usar proxy_pass , la configuración de http-timeout en uWSGI puede ayudar (no es la configuración de harakiri).

Como lo menciona @mahdix, el error puede deberse a que Nginx envía una solicitud con el protocolo uwsgi mientras uwsgi está escuchando en ese puerto los paquetes http.

Cuando en la configuración de Nginx tienes algo como:

 upstream org_app { server 10.0.9.79:9597; } location / { include uwsgi_params; uwsgi_pass org_app; } 

Nginx utilizará el protocolo uwsgi. Pero si en uwsgi.ini tienes algo como (o su equivalente en la línea de comandos):

 http-socket=:9597 

uwsgi hablará http, y aparecerá el error mencionado en la pregunta. Ver soporte nativo de HTTP .

Una posible solución es tener en su lugar:

 socket=:9597 

En cuyo caso, Nginx y uwsgi se comunicarán entre sí mediante el protocolo uwsgi a través de una conexión TCP.

Nota al margen: si Nginx y uwsgi están en el mismo nodo, un socket Unix será más rápido que TCP. Consulte el uso de sockets Unix en lugar de puertos .

Solucioné este problema al pasar la opción socket-timeout = 65 (archivo uwsgi.ini) o --socket-timeout=65 (línea de comando uwsgi) en uwsgi. Tenemos que comprobar con diferente valor depende del tráfico web. Este valor socket-timeout = 65 en el archivo uwsgi.ini funcionó en mi caso.

Tuve los mismos errores esporádicos en el despliegue de la aplicación Docker WSGI de Elastic Beanstalk. En la instancia EC2 de la configuración ascendente del entorno se ve así:

 upstream docker { server 172.17.0.3:8080; keepalive 256; } 

Con esta prueba de carga simple por defecto como:

 siege -b -c 16 -t 60S -T 'application/json' 'http://host/foo POST {"foo": "bar"}' 

… en el EC2 llevó a una disponibilidad de ~ 70%. El rest fueron 502 errores causados ​​por una conexión cerrada prematuramente en sentido ascendente mientras se leía el encabezado de respuesta desde el origen .

La solución fue eliminar la configuración de keepalive de la configuración en sentido ascendente, o lo que es más fácil y más razonable, es habilitar el mantenimiento de HTTP en el lado de --http-keepalive también, con --http-keepalive ( disponible desde 1.9 ).