Nginx e buffer de grandes respostas

Nginx e buffer de grandes respostas

Na configuração do nosso aplicativo, o nginx atua como um proxy reverso na frente do gunicorn.

Nosso aplicativo responde a solicitações de front-end com respostas pequenas, em geral... mas alguns endpoints geram respostas maiores que uma página de memória (4K).

Quando isso acontece, o nginx registra este aviso:

an upstream response is buffered to a temporary file 
/path/to/nginx/proxy_temp/4/86/0000000864 while reading upstream, 
client: 1.2.3.4, server: api.ourdomain.com, request: "GET /pdf/..."

Nossos logs nginx acabam inundados com esse aviso - e até onde posso ver, as únicas soluções para fazer esse aviso desaparecer de nossos logs sãosoluções ruins:

  • Posso definir o nginx proxy_max_temp_file_sizecomo 0 - basicamente desativando o buffer de respostas grandes. Isso interromperia o armazenamento em buffer dos arquivos - mas também significaria que, para endpoints que geram respostas grandes (por exemplo, geradores de PDF que criam respostas de 1 a 2 MB), um cliente de consumo lento paralisaria o trabalhador gunicorn correspondente... Na verdade, se houvesse são N trabalhadores gunicorn, seriam necessários apenas N clientes gerando PDFs por trás de conexões de rede lentas, e nosso aplicativo ficaria inativo ...

  • Posso aumentar proxy_buffer_sizepara mais de 4K (isto é, uma página de memória). Tenho certeza de que isso teria um impacto severo no desempenho do nginx - 70% de nossas respostas realmente cabem em 4K, e forçaríamos o nginx a alocar... o quê? 2 MB de buffers para cada um deles, apenas para estar pronto para solicitações ocasionais de geração de PDF? EDITAR: Na verdade isso não é uma opção de jeito nenhum – Michael (abaixo) comentou que os únicos valores permitidos são 4K e 8K.

  • Eu poderia desligar proxy_buffering- mas isso é tão ruim quanto a primeira solução (clientes lentos => morte).

Em essência, o nginx inunda nossos logs sobre algo que QUEREMOS - buffer temporário para arquivos quando as respostas são grandes.

Queremos apenas impedir que isso inunde nossos logs, "marcando-o" como não sendo realmente um aviso (nem sei por que isso é um aviso - sobre que "coisa ruim" ele está nos alertando?)

Além de editar nginxo código-fonte e recompilar, há alguma outra solução que esteja faltando?

Responder1

Isso é resultado do nível de log na diretiva error_log do Nginx.

https://www.nginx.com/resources/admin-guide/logging-and-monitoring/

error_log logs/error.log warn;

mensagens de níveis de aviso, erro crítico, alerta e emergência são registradas.

A configuração padrão do log de erros funciona globalmente. Para substituí-lo, coloque a diretiva error_log no contexto de configuração principal (nível superior). As configurações no contexto principal são sempre herdadas por outros níveis de configuração. A diretiva error_log também pode ser especificada nos níveis http, stream, servidor e local e substitui a configuração herdada dos níveis superiores.

Essa linha sobre buffer está no nível de aviso:

[warn] 30055#0: *1428 an upstream response is buffered to a temporary file 

Portanto, se você garantir que o nível do log de erros não esteja configurado para avisar, ou seja, deixá-lo no padrão ou diminuí-lo, você não verá mais esse aviso. Qualquer uma das soluções abaixo irá suprimi-los:

Deixe no padrão (nível 'erro' e superior):

error_log logs/error.log;

Mesma coisa:

error_log logs/error.log error;

Você também pode aumentar o limite além de error, até crit, alerte emerg.

informação relacionada