背景:Java应用后台服务有一个文件下载接口,通过页面触发并调用该下载接口进行文件下载。前端通过Ingress做请求转发(背后是Nginx代理),使用Chrome浏览器进行大于1GB文件下载的时候下载到1GB就突然报错 "网络错误"

排查过程:

1、下载小于1GB的文件正常;

2、不经过Ingress直接进入应用Pod采用命令行的方式调用下载接口下载大于1GB文件正常;

curl -v --location --request GET 'http://localhost:8080/api/file/download?key=xxx.tar.gz' --header 'Cookie: JSESSIONID=F0AB3381A7E8EC600DAE2FF86C0276C3' --output ./xxx.tar.gz

3、经过Ingress采用命令的方式调用下载接口下载大于1GB文件异常;

# -k --insecure 忽略https所需的TLS证书, -http1.1 指定HTTP协议版本
curl -v --location --request GET 'https://${domain}/api/baas/api/file/download?key=xxx.tar.gz' --header 'Cookie: Cookie: JSESSIONID=F0AB3381A7E8EC600DAE2FF86C0276C3' --output ./xxx.tar.gz  -k --insecure --http1.1

查看Ingress日志如下: 

# 下载开始时
2022/01/13 02:13:10 [warn] 29489#29489: *353766035 an upstream response is buffered to a temporary file /tmp/proxy-temp/0000013203 while reading upstream, client: 182.92.253.8, server: ...

# 下载出现异常时
2022/01/13 02:17:27 [error] 29489#29489: *353766035 upstream prematurely closed connection while reading upstream, client: 182.92.253.8, server: ...

综上,可基本定位问题出在Ingress代理。

解决:

经查,Ingress背后的 Ngnix 反向代理对Response默认开启了缓存,而缓冲区的大小跟proxy_buffer_size 和 proxy_buffers 有关。如果缓冲区无法装下所有的响应,则响应内容会写入到缓存文件中,缓存文件的大小上限由 proxy_max_temp_file_size 配置项指定,默认为1G。

因此,最简单的办法就是把 proxy_max_temp_file_size 配置的上限提高至大于要下载的文件大小。而我是基于Ingress 容器化来做的代理,因此需要修改应用Helm Chart下的Ingress对应yaml文件,在Ingress 组件下的metadata -> annotations 下添加如下配置项,重新打包并上传Chart至Harbor仓库更新安装即可。

nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "2048m"

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐