Nginx在发送最后一个区块之前关闭客户端连接

Nginx在发送最后一个区块之前关闭客户端连接,nginx,docker-compose,nginx-reverse-proxy,connection-close,Nginx,Docker Compose,Nginx Reverse Proxy,Connection Close,我第一次遇到这样的问题,我不知道如何找到解决办法 我当前的设置: 运行在Docker容器中的Nginx 运行在Docker容器中的PHP(带有FPM)项目,这取决于Nginx 全局安装在服务器上的Nginx,用于将连接转发到容器中 最终的客户端可以通过PHP项目下载大文件。PHP代码只是读取文件,并将其发送给客户端,其中包含一些标题(application/force download、application/octet stream、application/download等) 我的目标是

我第一次遇到这样的问题,我不知道如何找到解决办法

我当前的设置:

  • 运行在Docker容器中的Nginx
  • 运行在Docker容器中的PHP(带有FPM)项目,这取决于Nginx
  • 全局安装在服务器上的Nginx,用于将连接转发到容器中
最终的客户端可以通过PHP项目下载大文件。PHP代码只是读取文件,并将其发送给客户端,其中包含一些标题(application/force download、application/octet stream、application/download等)

我的目标是公平地停止Docker容器,但等待客户端完成下载

在Nginx Dockerfile中,我添加了
STOPSIGNAL SIGQUIT
行,因为Nginx没有使用SIGTERM进行优雅的关机

一切似乎都很好,客户端启动下载,我尝试“docker compose down”,nginx容器接收SIGQUIT并拒绝新连接,但每次客户端下载文件时都保持活动状态

最后,在发送最后一个数据块后,它会自动停止,没有任何错误

但是,在99.999%的下载量下,客户端收到“连接中断”

经过一些调查,它似乎每次错过不到8Mo(使用900 Mo文件和4 Go文件进行测试)

我发现服务器nginx(proxy_传递给容器)抛出以下错误:

2020/09/30 10:04:35[错误]1069853#1069853:*58334上游在读取上游时过早关闭连接,客户端:XXXX.XXX.X.X,服务器:mywebsite.io,请求:“GET/b/d/37edae880/4d55e8ec14546dc0 HTTP/2.0”,上游:http://127.0.0.1:8000/b/d/37edaee880/4d55e8ec14546dc0,主机:“mywebsite.io”

因此,它不会将文件的最后一部分提供给客户端。我不知道Nginx为什么抱怨“过早关闭连接”,因为在docker端,在发送所有文件后连接关闭:/

是否有任何配置可以避免这种情况

我可以给Docker nginx配置:

    listen 80;

    root /var/www/html/public;

    server_name _;

    index index.php;

    client_max_body_size 10G;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_read_timeout 600s; # 10m
    }
}
  server_name mywebsite.io;

  access_log /var/log/nginx/mywebsite.io.access.log;
  error_log /var/log/nginx/mywebsite.io.error.log error;

  include /etc/nginx/conf.d/server/default.conf;
  include /etc/nginx/conf.d/server/ssl.conf;
  include /etc/nginx/conf.d/server/csp.conf;
  
  location / {
    client_max_body_size 10G;
    client_body_timeout 43200s; # 12h
    proxy_read_timeout 1800s; # 30m
    proxy_max_temp_file_size 0;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Host $server_name;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_http_version      1.1;
    proxy_set_header        Upgrade $http_upgrade;
    proxy_set_header        Connection "upgrade";
    proxy_pass              http://127.0.0.1:8000;
  }
}
以及服务器Nginx配置:

    listen 80;

    root /var/www/html/public;

    server_name _;

    index index.php;

    client_max_body_size 10G;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_read_timeout 600s; # 10m
    }
}
  server_name mywebsite.io;

  access_log /var/log/nginx/mywebsite.io.access.log;
  error_log /var/log/nginx/mywebsite.io.error.log error;

  include /etc/nginx/conf.d/server/default.conf;
  include /etc/nginx/conf.d/server/ssl.conf;
  include /etc/nginx/conf.d/server/csp.conf;
  
  location / {
    client_max_body_size 10G;
    client_body_timeout 43200s; # 12h
    proxy_read_timeout 1800s; # 30m
    proxy_max_temp_file_size 0;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Host $server_name;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_http_version      1.1;
    proxy_set_header        Upgrade $http_upgrade;
    proxy_set_header        Connection "upgrade";
    proxy_pass              http://127.0.0.1:8000;
  }
}
两天来,我试图解决这个问题,但没有成功

谢谢

编辑

如果最终客户端连接到停靠的Nginx,则它可以正常工作。“bug”出现在界面nginx host->nginx docker