文件上传时,文件太大会有几种被限制的情况

文件上传时,文件太大会有几种被限制的情况

​ 近期在维护一个项目时,商户有反馈,在新增用户时会直接卡住并报错,返回一个异常,应用层没有日志,最后排查出来是nginx限制了请求的最大值.

​ 那么整个链路上都有哪些可能导致上传会被限制.比如前端页面表单输入数据较多,包含多个文本、多张图片,在数据未压缩的情况下,最终上传失败? 下面了梳理一下.

一个请求需要经过的路径:

nginx->servlet中间件->具体应用框架(springmvc,strust2)->内部rpc访问->数据库

下面这里汇总一下中间过程可能会导致限流的地方,以及需要调整的配置.

nginx

用nginx来做webserver的时,上传大文件时需要特别注意client_max_body_size这个参数,否则会中断在nginx的请求中是无法记录到访问的.

nginx 日志文件里会提示 send too large body:50746366(大概是50MB)

image-20201112140322430

image-20201112140322430

查看nginx的配置,进入:/usr/local/nginx/conf/nginx.conf(具体名字和路径可能不一样)

client_max_body_size 20m; 需要调整,(如果不配置则默认是1M)

sendfile        on;
#tcp_nopush     on;
#keepalive_timeout  0;
keepalive_timeout  65;
gzip  on;
client_max_body_size 20m; 
include upstream.conf;
limit_conn_zone $binary_remote_addr zone=one:10m;

tomcat

当服务器是Tomcat时,通过POST上传的文件大小的最大值为2M(2097152)

tomcat目录下的conf文件夹下,server.xml 文件中以下的位置中添加maxPostSize参数

<Connector port="8081" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="utf-8" maxPostSize="0" />

jetty

Jetty的默认值为200k,我们可以在配置内修改这个默认设置,修改JETTY_HOME/etc/jetty.xml,对maxFormContentSize重新赋值,-1表示不限制,正数值表示所允许的最大bytes:

jetty的参数文件 vim jetty.xml

<Configure id="Server" class="org.eclipse.jetty.server.Server">
添加
<Call name="setAttribute">
  <Arg>org.eclipse.jetty.server.Request.maxFormContentSize</Arg>
  <Arg>2000000</Arg>
 </Call>
<Call name="setAttribute">
  <Arg>org.eclipse.jetty.server.Request.maxFormKeys</Arg>
  <Arg>2000</Arg>
 </Call>

springboot 限制

1. 内置tomcat

修改Spring Boot内置Tomcat的maxPostsize值,在application.yml配置文件中添加以下内容

yaml 格式:

server:  
  tomcat:
    max-http-post-size: -1

properties格式:

server.tomcat.max-http-post-size=-1

2.springmvc 设置文件上传大小限制

springboot 配置

Spring Boot 1.3 或之前的版本,配置:

multipart.maxFileSize = 100Mb

multipart.maxRequestSize=150Mb

Spring Boot 1.4 版本后配置更改为:

spring.http.multipart.maxFileSize = 100Mb spring.http.multipart.maxRequestSize = 150Mb

Spring Boot 2.0 之后的版本配置修改为:( Mb改为MB了)

spring.servlet.multipart.max-file-size = 100MB spring.servlet.multipart.max-request-size = 150MB

如果是想要不限制文件上传的大小,那么就把两个值都设置为-1

文档地址:https://docs.spring.io/spring-boot/docs

具体的版本:选择版本后进入 reference/html 举例:https://docs.spring.io/spring-boot/docs/1.5.0.RC1/reference/html/


老版本xml的配置

maxInMemorySize: 此为阈值,低于此值,则保存在内存中,如高于此值,则生成硬盘上的临时文件

maxUploadSize: 一旦超过就上传失败!应该有异常处理器转发报错页面

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="UTF-8">
    <!--500*1024*1024 -->
       <property name="maxUploadSize"><value>524288000</value></property>
        <property name="maxInMemorySize"><value>4096</value></property>
</bean>

strust2 限制

一些老项目仍然使用的strust2的框架.

Struts2上传文件的默认大小限制是2M(2097152字节),可在struts配置文件里设置 上传文件的最大值struts.xml

<struts>
   <!-- 设置常量 上传文件大小最大值,系统默认是2M,此设置为100M(1024*1024*100=104857600) -->
    <constant name="struts.multipart.maxSize" value="104857600" />
</struts>

rpc框架限制

dubbo框架的限制

解决方案

  • 使用hessian协议进行传输 (参照dubbo 官网,或者搜索dubbo hessian )

  • 将文件转换成byte[]继续使用dubbo协议(这种情况一般用于上传文件跟业务有关联)

当传输协议为:dubbo协议时 默认是8M(8388608) 单位字节 (1M=1048576)

当dubbo服务提供层向消费层传输大数据容量的对象时,会受到Dubbo的限制,报类似如下异常:

com.alibaba.dubbo.remoting.transport.AbstractCodec.checkPayload() ERROR
Data length too large: 11557050, max payload: 8388608
java.io.IOException: Data length too large: 11557050, max payload: 8388608

调整内容

1、 统一修改提供方的dubbo配置,

在dubbo.properties 中增加如下

​ dubbo.protocol.dubbo.payload=11557050(默认为8M,即8388608)

2、特殊dubbo修改提供方的dubbo配置:

<dubbo:protocol name="dubbo" port="${rmi.protocol.rmi.port}" payload = "104857600"/>

如果是使用dubbo协议的话,是不支持 file,inputStream 这种文件,流的传输的.

这种没有限制,具体可以看一下. Dubbo服务 上传文件解决方案以及Hessian协议

DB限制

超出了数据库中最大允许数据包默认配置值(mysql)

Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (16800061 > 16777216). You can change this value on the server by setting the max_allowed_packet’ variable.

修改DB的max_allowed_packet值:

USE demo; set global max_allowed_packet = 310241024*10; # 改为30M show VARIABLES like '%max_allowed_packet%'; # 重启DB连接生效

Note:MySQLmax_allowed_packet 的 默认配置:16777216 = 16 * 1024 * 1024,即16M

参考文档

  1. Spring Boot配置内置Tomcat的maxPostSize值

  2. nginx 更改配置client_max_body_size nginx.conf 修改默认限制上传附件大小

  3. Dubbo限制大数据传输的解决方案

  4. dubbo(三)dubbo的文件上传

  5. Dubbo服务 上传文件解决方案以及Hessian协议

如果觉得文章对您有用,可以关注我的公众号 程序和猫 , 更加方便的交流.

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 前端可以通过以下几种方法来解决上传文件大的问题: 1. 限制文件大小:在前端代码中限制上传文件大小,如果文件大,就提示用户选择一个较小的文件。 2. 分块上传:将文件分成多个小块,分别上传,这样即使文件很大,也不会占用多的内存。 3. 压缩文件:在前端压缩文件,使得文件体积变小,再上传。 4. 后端处理:如果前端无法处理,也可以在后端进行处理,例如将大文件分块存储。 选择具体的解决方案取决于具体的需求和约束条件。 ### 回答2: 前端可以通过以下几种方式解决上传文件大的问题。 1. 文件大小限制:前端可以通过在文件上传控件中设置文件大小限制限制用户上传的文件最大大小。可以使用HTML5的File API来检查文件大小,在选择文件之前进行检查并给予用户相应的提示。 2. 断点续传:前端可以使用断点续传技术,将大文件分成多个小文件进行上传。当上传中断,用户重新上传只需要上传断点之后的文件部分,避免重复上传整个大文件。可以使用HTML5的File API对文件进行切割,或者使用第三方库进行切割和上传。 3. 压缩文件:前端可以在上传之前对大文件进行压缩,减小文件大小。可以使用第三方的文件压缩库进行文件压缩,然后再进行上传。 4. 服务器分片上传:将大文件分成多个小分片,分别上传到服务器。前端可以使用HTML5的File API对文件进行切割,将切割后的小分片并发地上传到服务器。服务器端接收到多个小分片后再进行合并。 5. 服务器端限制:前端可以向服务器发送文件大小信息,并在服务器端进行判断和限制。服务器端可以设置接收文件的最大大小,当前端上传的文件超过服务器的限制,服务器拒绝接收并返回相应提示给前端。 总而言之,前端可以通过文件大小限制、断点续传、文件压缩、服务器分片上传和服务器端限制等方式来解决上传文件大的问题。不同的解决方案可以根据实际情况进行选择和组合使用。 ### 回答3: 当遇到上传文件大的问题,前端可以采取以下方法来解决: 1. 设置前端限制:可以在前端进行文件大小限制。通过在文件上传的表单元素中添加"accept"属性,并指定文件类型,例如"accept=".png,.jpg",可以限制只接受指定类型的文件。另外,在表单元素中添加"maxlength"属性,可以限制上传文件大小,避免上传过大文件。 2. 对文件进行压缩:前端可以使用压缩算法,将文件进行压缩再上传。通过压缩文件,可以减小文件大小,提高上传速度。可以使用一些前端框架或者第三方库,如JSZip、image-compressor等来实现文件压缩功能。 3. 分片上传:将大文件分成小块进行上传。前端可以使用分片上传的方式,将文件分成多个小块,逐个进行上传。这样可以避免一次性上传大文件,减轻服务器负担,提高上传速度。一些前端框架或者第三方库,如Resumable.js、plupload等可以辅助实现分片上传功能。 4. 服务端限制:与前端限制结合使用,后端也可以对上传文件大小进行限制。在服务器端设置上传文件大小限制,当文件超过限制大小,可以返回错误信息,提醒用户重新选择文件或者压缩文件后再上传。 综上所述,前端可以通过设置前端限制、对文件进行压缩、分片上传以及结合后端限制来解决上传文件大的问题。通过这些方法,可以有效地减小上传文件大小,提高文件上传的效率和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值