使用场景
上传文件接口通过nginx反向代理到zuul, zuul再路由转发到实际文件上传服务
问题
当上传500M文件的时候产生OOM异常
定位
堆内存分配最大值 1g
分析dump文件发现大量的
byte[] buf=file.getBytes()
分析发现文件先经过了zuul,然后再交给文件上传服务,会在临时文件夹里生成两个临时文件,zuul生成一个,文件上传服务生成一个;并且,zuul的堆内存会随着文件的传入而变化,小文件无所谓,但是大文件,会使得堆内存急速增加,有可能是因为在zuul中使用类似了byte[] buf=file.getBytes()
这样的操作,当多个大文件同时传入,内存一下子挤满了堆空间,而且上传是一个慢性过程,jvm无法对正在处理的对象进行回收,就会产生OOM异常
文件超过 1024M*8/30 触发young gc,但是文件还没上传完,无法回收,就GG了
解决
查询zuul官方文档发现
如果您@EnableZuulProxy您可以使用代理路径上传文件,只要文件很小,它就应该工作。对于大文件,有一个替代路径绕过“/ zuul / *”中的Spring DispatcherServlet(以避免多部分处理)。也就是说,如果zuul.routes.customers=/customers/**则可以将大文件发送到“/ zuul / customers / *”。servlet路径通过zuul.servletPath进行外部化。如果代理路由引导您通过Ribbon负载均衡器,例如,超大文件也将需要提升超时设置
只需在zuul接口前加上/zuul即可绕过 原nginx配置
proxy_pass http://localhost:8111/upload
改为
proxy_pass http://localhost:8111/zuul/upload
注意:本文归作者所有,未经作者允许,不得转载