Zuul官网关于文件上传的说明

小文件可以正常工作,大文件需要通过/zuul/*这个替代路径来绕过spring(避免进行多部分处理)。另外大文件上传需要提高超时设置。

关于zuul的dispatcherServlet和zuulServlet,一般情况下zuulServlet被嵌入到Dispatch机制中,由DispatcherServlet分派处理,这样可以控制路由,并缓冲请求。如果需要绕过multipart处理,在不缓冲请求的情况下通过zuul,zuulServlet也可以装载在DIspatcher之外,让请求绕过DispatcherServlet。

DispatcherServlet为了方便后续处理流程使用,会将multipart/form请求根据RFC1867规则进行统一分析处理,并且返回MultipartHttpServletRequest实例,通过它可获取file和其他参数,这个过程会影响性能。

处理multipart/form请求的核心代码:

具体配置:

一、zuul路由配置:

serviceId映射:

zuul:

  routes:

    publicCommon:

      path: /myyule-public-common/**

      service-id: myyule-public-common

二、 ribbon及hystrix超时配置

hystrix:

  command:

    default:

      execution:

        timeout:

          enabled: true

        isolation:

          thread:

            timeoutInMilliseconds: 900000

myyule-public-common:

  ribbon:

    ReadTimeout: 600000  

ConnectTimeout: 600000

三、 文件上传请求地址加上zuul/

四、 文件上传耗时分析

上传一个大文件(约250M),跟踪请求日志打印如下:

主要耗时在网关到进入文件上传方法内部这一段,其中网关耗时应该较少,因为已经通过zuul/路径绕过了网关对文件的处理,所以分析主要耗时原因在接收MultipartFile这个参数这里。

MultipartFile对象的封装过程:

1.spring检测请求,是否是multipart,不是则返回http request,是,解析resolveMultipart(request) 返回默认的 DefaultMultipartHttpServletRequest。

2.将MultipartParsingResult参数融合在一起,就形成了DefaultMultipartHttpServletRequest对象;在这个对象可以拿到上传的文件MultipartFile

3.MultipartFile的由来。

CommonsMultipartFile file = createMultipartFile(fileItem);
 
FileItem fileItem = fac.createItem(item.getFieldName(),
item.getContentType(), item.isFormField(), fileName);
 
Streams.copy(item.openStream(), fileItem.getOutputStream(),
true);

MultipartFile由流复制而来。FileItem由FileItemFactory 接口创建,FileItemFactory默认由DiskFileItemFactory 实现。当上传的文件项目比较小时,直接保存在内存中(速度比较快),比较大时,以临时文件形式,保存在磁盘临时文件夹(速度较慢)。

属性:1) public static final int DEFAULT_SIZE_THRESHOLD :将文件保存在内存还是磁盘临时文件夹的默认临界值,值为10240,即10kb。

小结:大文件上传流程:(1)客户端发起上传请求——(2)网关接收请求并识别到zuul/路径,不对文件流进行处理直接放行——(3)请求转发到上传服务,先对文件流进行解析,将文件写到服务器本地(这一过程涉及到磁盘写入)——(4)上传文件业务处理并调用fastdfs——(5)返回上传结果。耗时主要在第三步。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注