http - nginx 代理请求缓冲未按预期工作

标签 http nginx file-upload upload tornado

这是我的 nginx 配置:

worker_processes auto;
user nginx;

events {
    worker_connections 1024;
    use epoll;
}

http {

    tcp_nodelay               on;
    add_header Cache-Control  no-cache;

    upstream servers {
        server                127.0.0.1:9999;
        server                127.0.0.1:9998;
    }

    proxy_request_buffering   on;

 server {
   listen 80;
   client_max_body_size 200M;
   client_body_buffer_size 200M;

   server_name           localhost;

        location / {
            try_files    $uri @proxy_upload;
        }

        location @proxy_upload {
            proxy_pass_request_body on;
            proxy_pass              http://servers;
        }

 }
}

我尝试上传文件,我正在做类似分块上传的事情,文件超过 2G,客户端以 block 的形式发送文件,nginx 和脚本都在工作,但 nginx 没有按预期工作

你看,我打开了 proxy_request_buffering,所以我希望 nginx 缓冲所有 200M 的文件,然后立即将它传递给后端(这是 tornado-python),但是 nginx 将它传递给后端 1M 或 2M block ,这种行为导致非常高的 cpu 使用率,更高的系统负载和更低的上传速度,这种行为与将 proxy_request_buffering 设置为关闭没有太大区别,所以我认为我在这里做错了

为什么 nginx 没有正确缓冲,我应该如何让 nginx 缓冲整个请求然后立即传递它?

我尝试使用 post_action,但无法将请求正文传递给后端

更新:Nginx 正在正确缓冲,我的意思是它会在客户端上传整个文件后立即将请求主体传递给后端,但是 Nginx 会将请求主体以较小的 block 传递给后端并且它不会立即传递它, 它有整个主体但不会立即传递整个主体,我如何告诉 nginx 立即将请求主体传递给后端?

最佳答案

看起来你需要打开proxy_buffering,设置proxy_buffers来设置缓冲区的数量和大小,可能还需要proxy_buffers_size来确保它不会过度使用内存:

location @proxy_upload {
    proxy_buffering on;
    proxy_buffers 10 200m;
    proxy_buffer_size 1000m;
    proxy_pass_request_body on;
    proxy_pass              http://servers;
}

不确定您的上游服务器有多少流量,但我可以想象这么大的缓冲区效率不高……您使用的上游网络服务器需要这么大的缓冲区?也许尝试将缓冲区一次增加 1 米,直到它处于合适的最佳位置。

发件人:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers

并且:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size

关于http - nginx 代理请求缓冲未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47125684/

相关文章:

laravel - 有什么方法可以加快 ffmpeg 处理时间

javascript - HTTP POST 和 Google Apps 脚本文件上传

http - 发送 HTTP header 后服务器无法设置内容类型

ssl - 续订 letsencrypt SSL 证书后,服务器仅返回响应代码 400

nginx - gke nginx ingress 创建额外的负载均衡器

ssl - 使用卸载到 ELB 的 SSL 解密在 AWS EC2 nginx 上的重定向中添加的无效端口

PHP文件上传

json - 是否可以使用 Stripe API 查询日期时间范围?

http - 在 linux 中对 'digest authentication' 使用 --digest 选项和 curl

android - 如何使用 flutter dio 下载文件?