文章目錄
Spring DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
前言
最近在項目中遇到了兩次org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
。
問題1:REST API接口返回JSON超過256K時報錯;
問題2:下載文件接口(返回二進制文件流,Content-Type爲application/octet-stream
)文件超過256K時報錯。
Spring版本:
- Spring Boot 2.2.2.RELEASE
- Spring Core 5.2.2.RELEASE
問題分析
項目基於Spring Cloud Gateway來開發了API網關,上面的錯誤都發生在API網關。
從日誌來看是典型的緩衝區溢出錯誤。
對問題1,只要加大緩衝區,或者限制返回JSON的大小就可以解決。
對問題2,寫文件流的方式,按道理寫入緩衝區的數據會被消費走,不應該出現緩衝區溢出錯誤。
問題解決過程
通過配置參數加大緩衝區
默認的緩衝區爲256K,可以通過配置spring.codec.max-in-memory-size
加大緩衝區:
spring:
codec:
max-in-memory-size: 2MB
關於該參數說明:
spring.codec.max-in-memory-size:
Limit on the number of bytes that can be buffered whenever the input stream needs to be aggregated. This applies only to the auto-configured WebFlux server and WebClient instances. By default this is not set, in which case individual codec defaults apply. Most codecs are limited to 256K by default.
不幸的是,該參數在Spring Boot 2.2.2.RELEASE 中不生效,在其它Spring Boot版本中可能生效。
參見:
- https://github.com/spring-projects/spring-boot/issues/18828
- https://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/appendix-application-properties.html
- https://docs.spring.io/autorepo/docs/spring-boot/2.2.2.RELEASE/reference/html/appendix-application-properties.html
通過配置類加大緩衝區
增加一個配置類來加大緩衝區:
@Configuration
@EnableWebFlux
@Slf4j
public class WebFluxWebConfig implements WebFluxConfigurer {
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024);
}
}
不幸的是,該配置類在Spring Boot 2.2.2.RELEASE 中不生效,在其它Spring Boot版本中可能生效。
參見:
限制接口返回JSON的大小
通過Jackson的@JsonInclude(JsonInclude.Include.NON_NULL)
註解在接口返回的JSON中過濾掉爲 null
的字段,以限制接口返回JSON的大小。
檢查網關的攔截器(Filter)是否操作了HTTP body
如果網關的攔截器(Filter)中操作了HTTP body,也可能會出現DataBufferLimitException的問題。
問題解決結果
對於問題一,由於不能改變項目中使用的Spring Boot的版本,無法採用加大緩衝區的方式,最終通過限制接口返回JSON的大小來解決。
對於問題二,對Content-Type爲application/octet-stream
時(返回二進制流時),不在網關的攔截器(Filter)中操作HTTP body來避免緩衝區溢出錯誤。