Nginx 和大响应的缓冲

tts*_*ras 6 nginx

在我们应用程序的配置中,nginx 在gunicorn.

我们的应用程序以一般来说较小的响应来回复前端请求……但某些端点生成的响应大于一个内存页 (4K)。

发生这种情况时,nginx 会记录此警告:

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/..."
Run Code Online (Sandbox Code Playgroud)

我们的 nginx 日志最终充斥着这个警告——据我所知,使这个警告从我们的日志中消失的唯一解决方案是糟糕的解决方案

  • 我可以将 nginx 设置proxy_max_temp_file_size为 0 - 基本上禁用大型响应的缓冲。这将停止对文件的缓冲——但这也意味着对于生成大量响应的端点(例如,生成 1-2MB 响应的 PDF 生成的端点),一个缓慢消耗的客户端会拖延相应的 gunicorn 工人......事实上,如果有是 N 个 gunicorn 工人,只需要 N 个客户端在慢速网络连接后生成 PDF,我们的应用程序就会关闭......

  • 我可以将其proxy_buffer_size增加到 4K 以上(即一个内存页)。我很确定这会对 nginx 性能产生严重影响 - 我们 70% 的响应确实适合 4K,我们会强制 nginx 分配......什么?他们每个人都有 2MB 的缓冲区,只是为偶尔的 PDF 生成请求做好准备? 编辑:事实上,这根本不是一个选项——迈克尔(下面)评论说,唯一允许的值是 4K 和 8K。

  • 我可以proxy_buffering关闭 - 但这和第一个解决方案一样糟糕(慢客户端 => 死亡)。

本质上,nginx 会淹没我们关于我们想要的东西的日志 - 当响应很大时临时缓冲到文件。

我们只是想阻止它淹没我们的日志,通过“标记”它不是真正的警告(我什至不确定为什么这是一个警告 - 它警告我们什么“坏事”?)

除了编辑nginx的源代码和重新编译之外,还有其他我缺少的解决方案吗?

小智 2

这是 Nginx 的 error_log 指令的日志级别的结果。

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

error_log logs/error.log warn;
Run Code Online (Sandbox Code Playgroud)

记录警告、错误暴击、警报和紧急级别的消息。

错误日志的默认设置全局有效。要覆盖它,请将 error_log 指令放置在主(顶级)配置上下文中。主上下文中的设置始终由其他配置级别继承。error_log 指令还可以在 http、流、服务器和位置级别指定,并覆盖从更高级别继承的设置。

关于缓冲的那行处于警告级别:

[warn] 30055#0: *1428 an upstream response is buffered to a temporary file 
Run Code Online (Sandbox Code Playgroud)

因此,如果您确保错误日志级别未设置为警告,即保留默认值或降低它,那么您将不会再看到该警告。以下任一解决方案都会抑制它们:

保留默认值(“错误”级别及以上):

error_log logs/error.log;
Run Code Online (Sandbox Code Playgroud)

一样:

error_log logs/error.log error;
Run Code Online (Sandbox Code Playgroud)

您还可以将阈值增加到超过error、最多critalertemerg