Spring DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144

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版本中可能生效。

參見:

通過配置類加大緩衝區

增加一個配置類來加大緩衝區:

@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來避免緩衝區溢出錯誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章