批量上传文件或者上传大文件时 gateWay报错DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
一、描述
最近在批量上传文件时网关出现了异常,后面发现上传大文件也会出现文件超过256发生异常,异常信息如下:
org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144 at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:101)
二、解决
1. 在配置文件中配置 max-in-memory-size: 1024MB
spring:
codec:
max-in-memory-size: 1024MB
结果:无效
2. 配置类中加大缓存
@Configuration
@EnableWebFlux
public class WebFluxWebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024);
}
}
结果:无效
3. 对网关过滤器或拦截器RequestBodyRoutePredicateFactory的操作
原代码:
public class RequestBodyRoutePredicateFactory
extends AbstractRoutePredicateFactory<RequestBodyRoutePredicateFactory.Config> {
protected static final Log LOGGER = LogFactory.getLog(RequestBodyRoutePredicateFactory.class);
private final List<HttpMessageReader<?>> messageReaders;
public RequestBodyRoutePredicateFactory() {
super(RequestBodyRoutePredicateFactory.Config.class);
this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
}
public RequestBodyRoutePredicateFactory(List<HttpMessageReader<?>> messageReaders) {
super(RequestBodyRoutePredicateFactory.Config.class);
this.messageReaders = messageReaders;
}
public static final String REQUEST_BODY_ATTR = "requestBodyAttr";
@Override
public AsyncPredicate<ServerWebExchange> applyAsync(Config config) {
return exchange -> {
if (!"POST".equals(exchange.getRequest().getMethodValue()) && !"PUT".equals(exchange.getRequest().getMethodValue())) {
return Mono.just(true);
}
Object cachedBody = exchange.getAttribute(REQUEST_BODY_ATTR);
if (cachedBody != null) {
try {
return Mono.just(true);
} catch (ClassCastException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Predicate test failed because class in predicate does not match the cached body object",
e);
}
}
return Mono.just(true);
} else {
return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> ServerRequest.create(exchange.mutate().request(serverHttpRequest).build(),
//this.messageReaders 的默认缓存还是256k
this.messageReaders).bodyToMono(String.class).defaultIfEmpty("").doOnNext((objectValue) -> {
if (StringUtils.isBlank(objectValue)) {
exchange.getAttributes().put(REQUEST_BODY_ATTR, JSON.toJSONString(exchange.getRequest().getQueryParams()));
} else {
exchange.getAttributes().put(REQUEST_BODY_ATTR, objectValue);
}
}).map((objectValue) -> true));
}
};
}
....
}
原因:原代码中获取body后,重新创建ServerRequest时,org.springframework.core.io.buffer.LimitedDataBufferList中判断接收数据大小超过制,org.springframework.core.codec.AbstractDataBufferDecoder中的默认262144。
具体可参考DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
解决办法:注入ServerCodecConfigurer,使用ServerCodecConfigurer.getReaders()获取相关配置。
public class RequestBodyRoutePredicateFactory
extends AbstractRoutePredicateFactory<RequestBodyRoutePredicateFactory.Config> {
protected static final Log LOGGER = LogFactory.getLog(RequestBodyRoutePredicateFactory.class);
//注入spring.codec.max-in-memory-size
@Autowired
ServerCodecConfigurer codecConfigurer;
private final List<HttpMessageReader<?>> messageReaders;
public RequestBodyRoutePredicateFactory() {
super(RequestBodyRoutePredicateFactory.Config.class);
this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
}
public RequestBodyRoutePredicateFactory(List<HttpMessageReader<?>> messageReaders) {
super(RequestBodyRoutePredicateFactory.Config.class);
this.messageReaders = messageReaders;
}
public static final String REQUEST_BODY_ATTR = "requestBodyAttr";
@Override
public AsyncPredicate<ServerWebExchange> applyAsync(Config config) {
return exchange -> {
if (!"POST".equals(exchange.getRequest().getMethodValue()) && !"PUT".equals(exchange.getRequest().getMethodValue())) {
return Mono.just(true);
}
Object cachedBody = exchange.getAttribute(REQUEST_BODY_ATTR);
if (cachedBody != null) {
try {
return Mono.just(true);
} catch (ClassCastException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Predicate test failed because class in predicate does not match the cached body object",
e);
}
}
return Mono.just(true);
} else {
return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) ->
//codecConfigurer.getReaders(),来获取spring.codec.max-in-memory-size的配置
ServerRequest.create(exchange.mutate().request(serverHttpRequest).build(),codecConfigurer.getReaders()).bodyToMono(String.class).defaultIfEmpty("").doOnNext((objectValue) -> {
if (StringUtils.isBlank(objectValue)) {
exchange.getAttributes().put(REQUEST_BODY_ATTR, JSON.toJSONString(exchange.getRequest().getQueryParams()));
} else {
exchange.getAttributes().put(REQUEST_BODY_ATTR, objectValue);
}
}).map((objectValue) -> true));
}
};
}
.....
}
结果:成功
批量上传文件或者上传大文件时 gateWay报错DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144的更多相关文章
- ThinkPHP 中入口文件中的APP_DEBUG为TRUE时不报错,改为FALSE时报错
今天好不容易将一个新闻网做好了(ThinkPHP框架做的),但是,当我将入口文件中定义调试模式设为FALSE,即define('APP_DEBUG',False),然后再刷新网站的时候,就提示报错,报 ...
- Loadrunner上传文件解决办法(大文件)
Loadrunner上传文件解决办法(大文件) 最近再做一个跟海量存储相关的项目测试,需要通过LR模拟用户大量上传和下载文件,请求是Rest或Soap,同时还要模拟多种大小尺寸不一的文件 通常情况下, ...
- Python组织文件 实践:查找大文件、 用Mb、kb显示文件尺寸 、计算程序运行时间
这个小程序很简单原本没有记录下来的必要,但在编写过程中又让我学到了一些新的知识,并且遇到了一些不能解决的问题,然后,然后就很有必要记录一下. 这个程序的关键是获取文件大小,本来用 os.path.ge ...
- 转:Loadrunner上传文件解决办法(大文件)
最近再做一个跟海量存储相关的项目测试,需要通过LR模拟用户大量上传和下载文件,请求是Rest或Soap,同时还要模拟多种大小尺寸不一的文件 通常情况下,都是使用简单的post协议即可: 方法一: we ...
- GitHub限制上传单个大于100M的大文件
工作中遇到这个问题,一些美术资源..unitypackage文件大于100M,Push到GitHub时被拒绝.意思是Push到GitHub的每个文件的大小都要求小于100M. 搜了一下,很多解决办法只 ...
- Facebook图片存储系统Haystack——存小文件,本质上是将多个小文件合并为一个大文件来降低io次数,meta data里存偏移量
转自:http://yanyiwu.com/work/2015/01/04/Haystack.html 一篇14页的论文Facebook-Haystack, 看完之后我的印象里就四句话: 因为[传统文 ...
- 【laravel5.4】git上clone项目到本地,配置和运行 项目报错:../vendor/aotuload.php不存在
1.一般我们直接使用git clone 将git的项目克隆下来,在本地git库和云上git库建立关联关系 2.vendor[扩展]文件夹是不会上传的,那么下载下来直接运行项目,会报错: D:phpSt ...
- 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射
内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileC ...
- 【基础巩固】文件流读写、大文件移动 FileStream StreamWriter File Path Directory/ ,m资料管理器(递归)
C#获取文件名 扩展名 string fullPath = @"d:\test\default.avi"; string filename = Path.GetFileName(f ...
随机推荐
- 什么是 Spring 的依赖注入?
依赖注入,是 IOC 的一个方面,是个通常的概念,它有多种解释.这概念是说你 不用创建对象,而只需要描述它如何被创建.你不在代码里直接组装你的组件和 服务,但是要在配置文件里描述哪些组件需要哪些服务, ...
- @Autowired 注解?
@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配. 它的用法和@Required 一样,修饰 setter 方法.构造器.属性或者具有任意名称 和/或多个参数的 PN 方 ...
- Netty学习摘记 —— 简单WEB聊天室开发
本文参考 本篇文章是对<Netty In Action>一书第十二章"WebSocket"的学习摘记,主要内容为开发一个基于广播的WEB聊天室 聊天室工作过程 请求的 ...
- 文档声明(Doctype)和<!Doctype html>有何作用? 严格模式与混杂模式如何区分?它们有何意义?
文档声明的作用: 文档声明是为了告诉浏览器,当前HTML文档使用什么版本的HTML来写的,这样浏览器才能按照声明的版本来正确的解析. <!doctype html> 的作用就是让浏览器进入 ...
- Mybatis插入数据
对上文->Mybatis快速入门-<进行代码修改 1.在UserMapper.xml中添加插入操作 <!-- 插入操作--> <insert id="save& ...
- centos7源码安装mysql5.7.19
centos7源码包安装mysql5.7 5.7.20安装方法和5.7.19的一样. 1.安装前准备 清空环境.安装相应的软件包 1>关闭防火墙和SELinux 2>配置yum源(阿里云, ...
- Oracle集群 & Grid(rac)配置,反推创建过程(重要)。
目前机器上,oracle都是安装好的,那么我们怎么知道,之前的安装过程大概是什么样子呢? 大致安装oracle集群的内容: 一.准备和配置: 1.网卡 2.ip资源 3.scanip 4.hosts ...
- Java 18 新功能介绍
文章持续更新,可以关注公众号程序猿阿朗或访问未读代码博客. 本文 Github.com/niumoo/JavaNotes 已经收录,欢迎Star. Java 18 在2022 年 3 月 22 日正式 ...
- python 面试题汇总
1丶元组(list)和列表(tuple)的区别: 一:共同点: ①: 可以放置任意数据类型的有序集合,都是可以存放数字,字符串,对象等. ②:都支持 负索引,切片,随意嵌套等操作 二:不同点: ①: ...
- xss攻击和防御
简介 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允 ...