nginx - 客户端请求主体被缓冲到临时文件中

nginx - 客户端请求主体被缓冲到临时文件中

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

a client request body is buffered to a temporary file /var/lib/nginx/body/0000000001

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

我将 增加到我期望上传的最大文件client_body_buffer_size大小1000m。然而,这只是一个猜测,虽然我不再收到该错误,但我想知道这是否是为 设置的合适值client_body_buffer_size

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

答案1

这是一个警告,而不是错误。这就是为什么[warn]在日志中以“”开头。

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

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

如果您有能力始终保留 1GB RAM 以用于偶尔的文件上传,那么这很好。将上传缓存在 RAM 中而不是磁盘上的临时文件中是一种性能优化,尽管对于如此大的上传量,多花几秒钟可能无关紧要。如果您的大多数上传量都很小,那么这可能是一种浪费。

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

答案2

如果你不想让 NginX 将正文内容存储在临时文件中,你可以像这样设置你的配置:

    client_body_buffer_size     10M;
    client_max_body_size        10M;

如果您将这两个配置都设置为相同的最大大小(分别以 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

答案3

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

proxy_request_buffering off;
proxy_http_version 1.1;
client_max_body_size 0;

如果您还想将评论复制到您的配置中:

# 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
指令详细信息
  • 还可以使用proxy_http_version 1.1因为正如proxy_request_bufferingdocs,在某些情况下请求缓冲仍然会处于开启状态:

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

禁用请求缓冲的理由

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

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

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

更多链接

  • 也可以看看此评论有关 nginx 如何进行代理缓冲的更详细解释,特别是proxy_request_buffering

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

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

相关内容