项目场景:
这个任务的主要目标是上传大文件,这些文件非常庞大,可以达到几百兆字节。需要确保上传过程的可靠性和稳定性,同时确保上传速度快,并且不会出现任何错误或中断。这个任务可能需要使用高速的互联网连接和专门的上传软件来完成。
问题描述
提示:直接走程序是没有问题的,会提示自定义错误,但是走nginx就直接502了
nginx配置属性client_max_body_size配置1G,但是服务端配置500M上传800M的文件nginx提示502。
springboot配置
spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB
502 Bad Gateway
前端页面请求
potmain请求
nginx请求的超时时间
proxy_read_timeout 200s;
proxy_connect_timeout 200s;
proxy_send_timeout 200s;
413Request Entity Too Large
nginx原始配置:
server {
listen 8090;
add_header X-Frame-Options "SAMEORIGIN";
# access_log "/dev/stdout" json;
client_max_body_size 1000m;
access_log "/opt/bitnami/nginx/logs/access-81.log" json;
location / {
root /html/ROOT81;
index index.html index.htm;
try_files $uri $uri/ ${uri}.html /index.html;
}
location ^~ /es/ {
alias /html/es81/;
index index.html index.htm;
try_files $uri $uri/ /es/index.html;
}
location ~* ^/admin|client/ {
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme; #Add-zwh
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 200s;
proxy_connect_timeout 200s;
proxy_send_timeout 200s;
proxy_pass http://gateway;
}
原因分析:
提示:事实证明还是nginx问题,直接用postman请求gateway没有问题
之后在测试本地环境发现,也会出奇的久,或许是不是环境不一致导致我看到的结果不一样。
nginx日志
failed (32: Broken pipe)
failed (104: Connection reset by peer)
-- 输出日志
{"remote_addr":"192.168.0.1","time":"2023-09-20T14:07:34+08:00","remote_user":"-","request_method":"POST","server_protocol":"HTTP/1.1","uri":"/admin/trade-ops/upload/record/upload/one/batch","args":"-","status":"502","body_bytes_sent":"150","upstream_addr":"192.168.0.236:8089","host":"192.168.0.236","gzip_ratio":"-","request_time":"22.242","request_length":"612276694","upstream_response_time":"0.000","upstream_status":"502","http_referer": "-","http_user_agent": "PostmanRuntime/7.33.0"}
-- 错误日志
2023/09/21 10:49:10 [error] 36#36: *7 writev() failed (32: Broken pipe) while sending request to upstream, client: 192.168.0.194, server: , request: "POST /admin/trade-ops/upload/record/upload/one/batch HTTP/1.1", upstream: "http://192.168.0.236:8089/admin/trade-ops/upload/record/upload/one/batch", host: "192.168.0.236:81"
2023/09/21 10:49:42 [error] 36#36: *7 readv() failed (104: Connection reset by peer) while reading upstream, client: 192.168.0.194, server: , request: "POST /admin/trade-ops/upload/record/upload/one/batch HTTP/1.1", upstream: "http://192.168.0.236:8089/admin/trade-ops/upload/record/upload/one/batch", host: "192.168.0.236:81"
2023/09/21 10:50:27 [warn] 1#1: conflicting server name "" on 0.0.0.0:8080, ignored
程序日志:
测试服务器一直打印的SizeLimitExceededException
异常
2023-09-20 17:27:48.525 [http-nio-8130-exec-2] [] ERROR com.timelinecapital.ops.common.exception.GlobalExceptionHand - Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (612276174) exceeds the configured maximum (524288000)
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (612276174) exceeds the configured maximum (524288000)
突然在本地跑一下看到FileSizeLimitExceededException
异常
2023-09-20 17:00:13.527 [http-nio-8088-exec-4] [] ERROR com.timelinecapital.ops.common.exception.GlobalExceptionHand:33 - Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field files exceeds its maximum permitted size of 209715200 bytes.
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field files exceeds its maximum permitted size of 209715200 bytes.
解决方案:
提示:定位问题还是得多多测试才对,多假设小心定位。方向错了就完了~
在异常盘里面加上e instanceof SizeLimitExceededException || e instanceof FileSizeLimitExceededException
好了短暂的异常解决了
@ExceptionHandler(Exception.class)
public ResponseEntity<?> sendErrorResponse(Exception e){
log.error(e.getMessage(), e);
if(e instanceof HttpMessageNotReadableException
|| e instanceof ServletException){
return OpsResponse.failure(ExceptionEnum.SYSTEM_BUSY);
} else if (e instanceof MaxUploadSizeExceededException
|| e instanceof SizeLimitExceededException
|| e instanceof FileSizeLimitExceededException) {
return ResponseEntity.ok(ResponseResult.failureMsg(ExceptionEnum.FILE_SIZE_OVER_LIMIT.getMsg()));
}
return OpsResponse.failure(ExceptionEnum.SYSTEM_EXCEPTION);
}
要不是看到突然本地环境多了一个特殊的异常信息FileSizeLimitExceededException仔细分析一下才发现,或许真是程序的问题不是nginx的问题,害我一直在配置nginx。然后不断测试发现还是一个坑对一次不对一次。
接着我把程序上传的文件配置改成了5M,发现上传文件10M一下子会提示异常,但当我上传900M的时候还是会提示502异常。我猜测应该是缓存问题,因为小文件一下子就触发了,大文件会出现问题,本身大文件会在短时间内占用信道导致传输出现问题,只是猜测。添加了 client_header_buffer_size配置,发现成功次数大大提高。
nginx添加或者修改如下配置
server {
client_header_buffer_size 1024m;
client_max_body_size 1000m;
client_body_timeout 600s;
client_body_temp_path /tmp;
client_header_timeout 600s;
location ~* ^/admin|client/ {
proxy_http_version 1.1;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_pass http://gateway;
#proxy_buffer_size 64k;
#proxy_buffers 32 32k;
#proxy_busy_buffers_size 128k;
#send_timeout 400s;
#proxy_buffer_size 64K;
#proxy_buffers 32 32K;
#proxy_busy_buffers_size 128K;
proxy_buffer_size 128k;
proxy_busy_buffers_size 192k;
proxy_buffers 4 192k;
正确回复的还是蛮高了,可能偶尔来一次网络问题,导致传输失败502其他的还是ok的
{"code":-1,"msg":"文件大小超过限制","data":null,"timestamp":1695284283482}
总结
我一直觉得这是一个nginx的配置问题,413问题倒是正常,因为本身就限制了传输,只是程序和nginx之间会有点出入,导致这个空隙到底谁来处理,这中间是个问题,况且文件还蛮大几百兆,先优化到这里吧,之后再贴个文继续后续优化,优化需要灵感需要时间不是一蹴而就。
引用
https://juejin.cn/post/7111514489182224392
https://blog.csdn.net/guo_qiangqiang/article/details/89675720
https://blog.csdn.net/zzhongcy/article/details/89090193
PS:参与本次活动的博文请务必添加「1024程序员节」标签,并在文章末尾加上小尾巴:
本文参与了「1024 程序员节」活动,欢迎正在阅读的你也加入。
使用 Markdown 编辑的小伙伴可直接复制以下内容到文章末尾:
本文参与了1024 程序员节活动,欢迎正在阅读的你也加入。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。