nginx - 客户端请求正文被缓冲到一个临时文件

Abs*_*Abs 84 nginx

每次尝试上传大文件时,我的日志文件中都会出现以下错误。

a client request body is buffered to a temporary file /var/lib/nginx/body/0000000001
Run Code Online (Sandbox Code Playgroud)

虽然文件上传成功,但我总是收到上述错误。

我增加了client_body_buffer_size1000m这是我所期望的上传是最大的文件。但是,这只是一个猜测,虽然我不再收到该错误,但我想知道这是否是为client_body_buffer_size?

如果有人能阐明该指令以及如何使用它,我将不胜感激。

Mic*_*ton 78

这是警告,而不是错误。这就是为什么它以[warn]日志开头。

这意味着上传文件的大小大于为上传保留的内存缓冲区。

该指令client_body_buffer_size控制该缓冲区的大小。

如果您有能力始终为偶尔的文件上传保留 1GB 的 RAM,那就没问题了。将上传缓冲在 RAM 中而不是在磁盘上的临时文件中是一种性能优化,尽管对于如此大的上传,额外的几秒钟可能无关紧要。如果您上传的大部分内容都很小,那么这可能是一种浪费。

最后,只有您才能真正决定合适的尺寸。

  • 你的回答帮助我做出了决定。我会将值降低到大约 512k 到 1m。很遗憾我会收到很多这样的警告。 (7认同)
  • 如果我将其设置为 50MB 并让 200 人同时查看一个页面,这会占用 10GB 的内存,还是仅分配给执行文件上传的任何用户的 50MB? (4认同)
  • @Codemonkey 该缓冲区仅在上传请求正文时使用。上传完成后,内存可用于另一个请求。正如另一位评论者指出的那样,虽然上传尚未进行,但不会使用内存。因此,这取决于您在任何给定时刻同时进行的上传数量。 (2认同)

edd*_*5br 26

如果您不想 NginX 将正文内容存储在临时文件中,您可以设置您的 config.xml 文件。像这样:

    client_body_buffer_size     10M;
    client_max_body_size        10M;
Run Code Online (Sandbox Code Playgroud)

如果您将这两个配置设置为相同的最大值。大小(分别以 k、M 或 G 表示 kB、MB 或 GB),您将防止 NginX 创建临时文件。文件。

有关更多信息:http : //nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_sizehttp://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size

  • 但是使用该配置,您还将阻止所有大于 10 MiB 的上传 (12认同)
  • @OmarOthman,由于 `client_max_body_size` 参数,约瑟夫是对的。请参阅此链接上的信息:[client_max_body_size doc.](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size):`设置客户端请求正文的最大允许大小,在“ Content-Length”请求头字段。如果请求中的大小超过配置值,则向客户端返回 413(请求实体太大)错误。请注意,浏览器无法正确显示此错误。将 size 设置为 0 将禁用对客户端请求正文大小的检查。` (11认同)
  • @eddy85br 谢谢。我不得不执行`proxy_buffering off;` 来关闭响应缓冲和`proxy_request_buffering off;` 来关闭请求缓冲。`proxy_cache off;` 是关于缓存响应,默认情况下它是关闭的。:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache (4认同)

nh2*_*nh2 11

如果 nginx 反向代理的上游服务器支持大文件的流式上传,那么最有意义的是完全禁用 nginx 缓冲这些上传,使用:

proxy_request_buffering off;
proxy_http_version 1.1;
client_max_body_size 0;
Run Code Online (Sandbox Code Playgroud)

如果您还想将注释复制到您的配置中:

# Explanation:
#     proxy_request_buffering off; -- upstream server can handle large streaming uploads
#     proxy_http_version 1.1;      -- required to disable request buffering also for clients that send chunked encoding
#     client_max_body_size 0;      -- otherwise nginx imposes a size restriction; only upstream should decide that
Run Code Online (Sandbox Code Playgroud)
指令详情
  • 还可以使用proxy_http_version 1.1,因为如proxy_request_buffering文档中所述,在某些情况下请求缓冲仍然会打开:

    当[客户端]使用HTTP/1.1分块传输编码时,无论指令值如何,请求正文都将被缓冲

禁用请求缓冲的基本原理

在这种情况下,nginx 存储请求是没有意义的:

  • 它会延迟您的上游应用程序看到它。
    • 这也意味着它不能提前返回错误,例如“权限被拒绝”;对于用户来说,在等待 30 分钟上传之后才知道这一点是很糟糕的用户体验。
  • 它不必要地消耗额外的磁盘空间。
    • 这会带来意想不到的不可靠性:人们可能认为对于“仅直通”的代理服务器来说,只有网络和 RAM 才是重要的;他们不认为如果磁盘太小,请求就会失败。
  • 磁盘 IO 通常很慢。

缓冲整个请求正文是为无法处理慢流上传的上游应用程序(例如具有最大运行时间的 PHP 脚本)而设计的。如果您的上游应用程序没有这样的限制,则不需要请求缓冲来解决它。

更多链接

  • 另请参阅此评论,以获取有关 nginx 如何进行代理缓冲的更详细说明,特别是proxy_request_buffering.

    在我放在那里的链接中,一位 nginx 开发人员解释了为什么对于(客户端 <- nginx)连接,一些缓存仍然是有益的。但是对于(nginx <-upstream),“某些缓存”目前是不可能的,因为proxy_request_buffering总是完全缓冲整个客户端请求并且根本不进行流式处理。

  • 这篇文章描述了另一个方向的代理缓冲(客户端 <- nginx):https://www.getpagespeed.com/server-setup/nginx/tuning-proxy_buffer_size-in-nginx 特别查看部分禁用代理缓冲?,它的参数与我上面的 (nginx -> proxy) 的参数类似。