一、描述

最近在批量上传文件时网关出现了异常,后面发现上传大文件也会出现文件超过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的更多相关文章

  1. ThinkPHP 中入口文件中的APP_DEBUG为TRUE时不报错,改为FALSE时报错

    今天好不容易将一个新闻网做好了(ThinkPHP框架做的),但是,当我将入口文件中定义调试模式设为FALSE,即define('APP_DEBUG',False),然后再刷新网站的时候,就提示报错,报 ...

  2. Loadrunner上传文件解决办法(大文件)

    Loadrunner上传文件解决办法(大文件) 最近再做一个跟海量存储相关的项目测试,需要通过LR模拟用户大量上传和下载文件,请求是Rest或Soap,同时还要模拟多种大小尺寸不一的文件 通常情况下, ...

  3. Python组织文件 实践:查找大文件、 用Mb、kb显示文件尺寸 、计算程序运行时间

    这个小程序很简单原本没有记录下来的必要,但在编写过程中又让我学到了一些新的知识,并且遇到了一些不能解决的问题,然后,然后就很有必要记录一下. 这个程序的关键是获取文件大小,本来用 os.path.ge ...

  4. 转:Loadrunner上传文件解决办法(大文件)

    最近再做一个跟海量存储相关的项目测试,需要通过LR模拟用户大量上传和下载文件,请求是Rest或Soap,同时还要模拟多种大小尺寸不一的文件 通常情况下,都是使用简单的post协议即可: 方法一: we ...

  5. GitHub限制上传单个大于100M的大文件

    工作中遇到这个问题,一些美术资源..unitypackage文件大于100M,Push到GitHub时被拒绝.意思是Push到GitHub的每个文件的大小都要求小于100M. 搜了一下,很多解决办法只 ...

  6. Facebook图片存储系统Haystack——存小文件,本质上是将多个小文件合并为一个大文件来降低io次数,meta data里存偏移量

    转自:http://yanyiwu.com/work/2015/01/04/Haystack.html 一篇14页的论文Facebook-Haystack, 看完之后我的印象里就四句话: 因为[传统文 ...

  7. 【laravel5.4】git上clone项目到本地,配置和运行 项目报错:../vendor/aotuload.php不存在

    1.一般我们直接使用git clone 将git的项目克隆下来,在本地git库和云上git库建立关联关系 2.vendor[扩展]文件夹是不会上传的,那么下载下来直接运行项目,会报错: D:phpSt ...

  8. 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射

    内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileC ...

  9. 【基础巩固】文件流读写、大文件移动 FileStream StreamWriter File Path Directory/ ,m资料管理器(递归)

    C#获取文件名 扩展名 string fullPath = @"d:\test\default.avi"; string filename = Path.GetFileName(f ...

随机推荐

  1. Eclipse建立Web项目,手动生成web.xml文件

    相关文章:https://blog.csdn.net/ys_code/article/details/79156188(Web项目建立,手动生成web.xml文件

  2. 什么是 spring 装配?

    当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配.Spring 容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定 在一起,同时装配 b ...

  3. servlet中的ServletContext对象

    ServletContext官方叫Servlet上下文.服务器会为每一个Web应用创建一个ServletContext对象.这个对象全局唯一,而且Web应用 中的所有Servlet都共享这个对象(在整 ...

  4. STM32 之 HAL库(固件库) _

    1 STM32的三种开发方式 通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的.一般大多数都会选用标准库和HAL库,而极少部分人会通过直 ...

  5. 一个未知宽高的元素在div中垂直水平居中

    <body> <div id="#div1"> <img src="img1.png"></img> </ ...

  6. vue重构--H5--canvas实现粒子时钟

    上一篇文章讲解了如何用js+canvas实现粒子时钟,本篇文章 ,主要是使用vue重构,让它在vue也能使用. 我们使用简单的方式重构,不使用vue工程,先加入vue cdn的地址,如下: <s ...

  7. 前端面试题整理——webpack相关考点

    webpack是开发工具,面试考点重点在配置和使用,原理理解不需要太深. 一.基本配置 1.拆分配置和merge 将公共配置跟dev和prod的配置拆分,然后通过webpack-merge对配置进行整 ...

  8. java中异常到底有什么用?举例

    异常的意义:马克-to-win:通过上面的例子,我们看出通过引入异常这种技术,即使出现不测(用户把0赋给除数),也可以让程序不崩溃,还能继续优雅 的运行.那,这种技术有用,值得学.马克-to-win: ...

  9. Python爬虫报错:"HTTP Error 403: Forbidden"

    错误原因:主要是由于该网站禁止爬虫导致的,可以在请求加上头信息,伪装成浏览器访问User-Agent. 新增user-agent信息: headers = {'User-Agent':'Mozilla ...

  10. String和int、long、double等基本数据类型的转换

    学习目标: 掌握Java的基本数据类型与String的转换 学习内容: 1.转化规则 String 转 基本数据类型 基本数据类型 变量 = 包装类.Parse基本数据类型(String); // c ...