最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Cloud Gateway 緩存區(qū)異常問題及解決方案

 更新時間:2024年06月13日 09:48:31   作者:小徐很努力  
最近在測試環(huán)境spring cloud gateway突然出現(xiàn)了異常,接下來通過本文給大家介紹Spring Cloud Gateway 緩存區(qū)異常問題解決方案,需要的朋友可以參考下

最近在測試環(huán)境spring cloud gateway突然出現(xiàn)了異常,在這里記錄一下,直接上干貨

1、問題背景

測試環(huán)境spring cloud gateway遇到以下異常

DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144(超出了緩沖區(qū)的最大字節(jié)數(shù)限制)

乍一看,問題很簡單啊,通過配置加大緩存區(qū)不就行了啊,于是就在application.yml加了以下配置

#將緩存區(qū)設置為2m
spring:
  codec:
    max-in-memory-size: 2MB

可是問題又出現(xiàn)了,通過調(diào)試發(fā)現(xiàn)配置的max-in-memory-size在程序啟動初始化確實是生效的。但是有業(yè)務調(diào)用的時候,此參數(shù)的接收值為null,maxInMemorySize還是讀取的默認值(256K)。

那咋整,只能從源碼入手了。

2、分析源碼過程

通過異常日志,可以定位到異常位置

后來發(fā)現(xiàn)我們自定義的攔截器獲取body的信息是獲取方式,代碼如下

因為HandlerStrategies.withDefaults() 是每次都需要重新創(chuàng)建對象,并非是spring注入的對象,所以每次獲取的都是默認值,導致配置不生效。

3、解決辦法

在我們自定的攔截器中注入ServerCodecConfigurer類,通過該類獲取配置。這樣獲取到的就是我們在application.yml中配置的緩存區(qū)配置的字節(jié)數(shù)限制了。

具體代碼:

@Component
@Slf4j
public class RequestFilter implements GlobalFilter, Ordered {
    @Override
    public int getOrder() {
        return OrderedConstant.HIGHEST_PRECEDENCE;
    }
    //手動注入ServerCodecConfigurer
    @Autowired
    ServerCodecConfigurer codecConfigurer;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        long startTime = System.currentTimeMillis();
        try {
            final Log logDTO = new Log();
            ServerHttpRequest request = exchange.getRequest();
            // 設置X-Request-Id
            AtomicReference<String> requestId = new AtomicReference<>(GenerateIdUtils.requestIdWithUUID());
            Consumer<HttpHeaders> httpHeadersConsumer = httpHeaders -> {
                String headerRequestId = request.getHeaders().getFirst(HeaderConstant.REQUEST_ID);
                if (!Strings.isNullOrEmpty(headerRequestId)) {
                    requestId.set(headerRequestId);
                }
                logDTO.setRequestId(requestId.get());
                httpHeaders.set(HeaderConstant.REQUEST_ID, requestId.get());
                httpHeaders.set(HeaderConstant.START_TIME_KEY, String.valueOf(startTime));
            };
            // codecConfigurer.getReaders()獲取pplication.yml中配置的緩存區(qū)配置的字節(jié)數(shù)
            ServerRequest serverRequest = ServerRequest.create(exchange,
                    codecConfigurer.getReaders());
            URI requestUri = request.getURI();
            String uriQuery = requestUri.getQuery();
            String url = requestUri.getPath() + (!Strings.isNullOrEmpty(uriQuery) ? "?" + uriQuery : "");
            HttpHeaders headers = request.getHeaders();
            MediaType mediaType = headers.getContentType();
            String method = request.getMethodValue().toUpperCase();
            // 原始請求體
            final AtomicReference<String> requestBody = new AtomicReference<>();
            final AtomicBoolean newBody = new AtomicBoolean(false);
            if (mediaType != null && LogHelper.isUploadFile(mediaType)) {
                requestBody.set("上傳文件");
            } else {
                if (method.equals("GET")) {
                    if (!Strings.isNullOrEmpty(uriQuery)) {
                        requestBody.set(uriQuery);
                    }
                } else {
                    newBody.set(true);
                }
            }
            logDTO.setLevel(Log.LEVEL.INFO);
            logDTO.setRequestUrl(url);
            logDTO.setRequestBody(requestBody.get());
            logDTO.setRequestMethod(method);
            logDTO.setIp(IpUtils.getClientIp(request));
            ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().headers(httpHeadersConsumer).build();
            ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();
            return build.getSession().flatMap(webSession -> {
                logDTO.setSessionId(webSession.getId());
                if (newBody.get() && headers.getContentLength() > 0) {
                    Mono<String> bodyToMono = serverRequest.bodyToMono(String.class);
                    return bodyToMono.flatMap(reqBody -> {
                        logDTO.setRequestBody(reqBody);
                        // 重寫原始請求
                        ServerHttpRequestDecorator requestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
                                DataBuffer bodyDataBuffer = nettyDataBufferFactory.wrap(reqBody.getBytes());
                                return Flux.just(bodyDataBuffer);
                            }
                        };
                        return chain.filter(exchange.mutate()
                                .request(requestDecorator)
                                .build()).then(LogHelper.doRecord(logDTO));
                    });
                } else {
                    return chain.filter(exchange).then(LogHelper.doRecord(logDTO));
                }
            });
        } catch (Exception e) {
            log.error("請求日志打印出現(xiàn)異常", e);
            return chain.filter(exchange);
        }
    }
}

到此這篇關于Spring Cloud Gateway 緩存區(qū)異常的文章就介紹到這了,更多相關Spring Cloud Gateway 緩存區(qū)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Springboot 限制IP訪問指定的網(wǎng)址實現(xiàn)

    Springboot 限制IP訪問指定的網(wǎng)址實現(xiàn)

    本文主要介紹了Springboot 限制IP訪問指定的網(wǎng)址實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • SpringBoot+Vue前后端分離實現(xiàn)請求api跨域問題

    SpringBoot+Vue前后端分離實現(xiàn)請求api跨域問題

    這篇文章主要介紹了SpringBoot+Vue前后端分離實現(xiàn)請求api跨域問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • 淺談Java當作數(shù)組的幾個應用場景

    淺談Java當作數(shù)組的幾個應用場景

    數(shù)組可以存放多個同一類型的數(shù)據(jù),可以存儲基本數(shù)據(jù)類型,引用數(shù)據(jù)類型(對象),下面這篇文章主要給大家介紹了關于Java當作數(shù)組的幾個應用場景,需要的朋友可以參考下
    2022-11-11
  • java 中動態(tài)代理(JDK,cglib)實例代碼

    java 中動態(tài)代理(JDK,cglib)實例代碼

    這篇文章主要介紹了java 中動態(tài)代理,這里介紹了JDK 動態(tài)代理與 cglib 動態(tài)代理的相關資料
    2017-04-04
  • Netty事件循環(huán)主邏輯NioEventLoop的run方法分析

    Netty事件循環(huán)主邏輯NioEventLoop的run方法分析

    這篇文章主要介紹了Netty事件循環(huán)主邏輯NioEventLoop的run方法分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • Java自帶的Http?Server實現(xiàn)設置返回值的類型(content-type)

    Java自帶的Http?Server實現(xiàn)設置返回值的類型(content-type)

    這篇文章主要介紹了Java自帶的Http?Server實現(xiàn)設置返回值的類型(content-type),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Spring boot隨機端口你都不會還怎么動態(tài)擴容

    Spring boot隨機端口你都不會還怎么動態(tài)擴容

    這篇文章主要介紹了Spring boot隨機端口你都不會還怎么動態(tài)擴容,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Mybatis中注解@MapKey的使用方式

    Mybatis中注解@MapKey的使用方式

    MyBatis使用@MapKey注解進行連表查詢,返回一個Map集合,Map的key為每條記錄的主鍵或指定字段,value為該記錄的字段名稱和字段值
    2024-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)之平衡二叉樹的實現(xiàn)詳解

    Java數(shù)據(jù)結(jié)構(gòu)之平衡二叉樹的實現(xiàn)詳解

    平衡二叉樹又被稱為AVL樹(有別于AVL算法),且具有以下性質(zhì):它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。本文將詳解介紹一下平衡二叉樹的原理與實現(xiàn),需要的可以參考一下
    2022-03-03
  • JAVA 創(chuàng)建線程池的注意事項

    JAVA 創(chuàng)建線程池的注意事項

    這篇文章主要介紹了JAVA 創(chuàng)建線程池的注意事項,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07

最新評論

阳曲县| 龙口市| 萝北县| 凌源市| 烟台市| 宜州市| 墨江| 海林市| 四会市| 鹤庆县| 利辛县| 仁化县| 平果县| 永昌县| 青海省| 仙居县| 青浦区| 德化县| 汪清县| 河北区| 自贡市| 衡南县| 大洼县| 三台县| 胶南市| 缙云县| 遵义县| 修武县| 丰宁| 陆河县| 尉氏县| 陇南市| 社旗县| 阳城县| 蒲城县| 禹城市| 张北县| 荆州市| 墨脱县| 文成县| 岳池县|