日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Spring Cloud Gateway 內(nèi)存溢出的解決方案

瀏覽:16日期:2023-07-01 18:51:38
記 Spring Cloud Gateway 內(nèi)存溢出查詢過程環(huán)境配置: org.springframework.boot : 2.1.4.RELEASEorg.springframework.cloud :Greenwich.SR1事故記錄:

由于網(wǎng)關(guān)存在 RequestBody 丟失的情況,顧采用了網(wǎng)上的通用解決方案,使用如下方式解決:

@Beanpublic RouteLocator tpauditRoutes(RouteLocatorBuilder builder) { return builder.routes().route('gateway-post', r -> r.order(1) .method(HttpMethod.POST) .and() .readBody(String.class, requestBody -> {return true;}) # 重點在這 .and() .path('/gateway/**') .filters(f -> {f.stripPrefix(1);return f;}) .uri('lb://APP-API')).build();}

測試環(huán)境,Spring Cloud Gateway 網(wǎng)關(guān)功能編寫完成。開始進(jìn)行測試環(huán)境壓測。

正常采用梯度壓測方式,最高用戶峰值設(shè)置為400并發(fā)。經(jīng)歷兩輪時長10分鐘左右壓測,沒有異常情況出現(xiàn)。

中午吃飯時間,設(shè)置了1個小時的時間進(jìn)行測試。

回來的時候系統(tǒng)報出如下異常

2019-08-12 15:06:07,296 1092208 [reactor-http-server-epoll-12] WARN io.netty.channel.AbstractChannelHandlerContext.warn:146 - An exception ’{}’ [enable DEBUG level for full stacktrace] was thrown by a user handler’s exceptionCaught() method while handling the following exception:io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 503316487, max: 504889344) at io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.java:640) at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:594) at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:764) at io.netty.buffer.PoolArena$DirectArena.newChunk(PoolArena.java:740) at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:244) at io.netty.buffer.PoolArena.allocate(PoolArena.java:214) at io.netty.buffer.PoolArena.allocate(PoolArena.java:146) at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:324) at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:185) at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:176) at io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:137) at io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator$MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.java:114) at io.netty.channel.epoll.EpollRecvByteAllocatorHandle.allocate(EpollRecvByteAllocatorHandle.java:72) at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:793) at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe$1.run(AbstractEpollChannel.java:382) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:315) at io.

當(dāng)時一臉懵逼,馬上開始監(jiān)控 Jvm 堆棧,減少jvm的內(nèi)存空間,提升并發(fā)數(shù)以后,重啟項目重新壓測,

項目啟動參數(shù)如下:

java -jar -Xmx1024M /opt/deploy/gateway-appapi/cloud-employ-gateway-0.0.5-SNAPSHOT.jar↓↓↓↓修改為↓↓↓↓java -jar -Xmx512M /opt/deploy/gateway-appapi/cloud-employ-gateway-0.0.5-SNAPSHOT.jar

縮減了一半內(nèi)存啟動,等待問題復(fù)現(xiàn)。等待3分鐘問題再次復(fù)現(xiàn),但是同時Jvm卻的進(jìn)行了Full GC。

EC EUOC OU MC MU CCSC CCSU YGC YGCT FGC FGCT 275456.0 100103.0 484864.0 50280.2 67672.0 64001.3 9088.0 8463.2 501 11.945 3 0.262 275968.0 25072.3 484864.0 47329.3 67672.0 63959.4 9088.0 8448.8 502 11.970 4 0.429

沒錯,在出現(xiàn)問題的時候,系統(tǒng)出現(xiàn)了Full Gc,但是OU并沒有達(dá)到觸發(fā)的原因。

結(jié)合日志中的 direct memory,想到了Jvm 中的堆外內(nèi)存。

使用 -XX:MaxDirectMemorySize 可以進(jìn)行設(shè)置 Jvm 堆外內(nèi)存大小,當(dāng) Direct ByteBuffer 分配的堆外內(nèi)存到達(dá)指定大小后,即觸發(fā)Full GC。

該值是有上限的,默認(rèn)是64M,最大為 sun.misc.VM.maxDirectMemory()。

結(jié)合所有情況,表明堆外內(nèi)存使用存在內(nèi)存溢出的情況。

報錯內(nèi)容為Netty框架,新增以下配置,開啟Netty錯誤日志打印:

-Dio.netty.leakDetection.targetRecords=40 #設(shè)置Records 上限-Dio.netty.leakDetection.level=advanced #設(shè)置日志級別項目啟動,沒任何問題,開啟壓測后服務(wù)報出如下異常:

2019-08-13 14:59:01,656 18047 [reactor-http-nio-7] ERROR io.netty.util.ResourceLeakDetector.reportTracedLeak:317 - LEAK: ByteBuf.release() was not called before it’s garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.Recent access records: #1:org.springframework.core.io.buffer.NettyDataBuffer.release(NettyDataBuffer.java:301)org.springframework.core.io.buffer.DataBufferUtils.release(DataBufferUtils.java:420)org.springframework.core.codec.StringDecoder.decodeDataBuffer(StringDecoder.java:208)org.springframework.core.codec.StringDecoder.decodeDataBuffer(StringDecoder.java:59)org.springframework.core.codec.AbstractDataBufferDecoder.lambda$decodeToMono$1(AbstractDataBufferDecoder.java:68)reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:107)reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103)reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287)reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331)reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1505)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onComplete(MonoCollectList.java:123)reactor.core.publisher.FluxJust$WeakScalarSubscription.request(FluxJust.java:101)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onSubscribe(MonoCollectList.java:90)reactor.core.publisher.FluxJust.subscribe(FluxJust.java:70)reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:54)reactor.core.publisher.MonoCollectList.subscribe(MonoCollectList.java:59)reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:44)reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:56)reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)reactor.core.publisher.MonoPeek.subscribe(MonoPeek.java:71)reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103)reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287)reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331)reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1505)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onComplete(MonoCollectList.java:123)reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252)reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:372)reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:196)reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:337)reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:333)reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:453)reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:141)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:191)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323)io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297)io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:677)io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:612)io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:529)io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:491)io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)java.lang.Thread.run(Unknown Source)#2:io.netty.buffer.AdvancedLeakAwareByteBuf.nioBuffer(AdvancedLeakAwareByteBuf.java:712)org.springframework.core.io.buffer.NettyDataBuffer.asByteBuffer(NettyDataBuffer.java:266)org.springframework.core.codec.StringDecoder.decodeDataBuffer(StringDecoder.java:207)org.springframework.core.codec.StringDecoder.decodeDataBuffer(StringDecoder.java:59)org.springframework.core.codec.AbstractDataBufferDecoder.lambda$decodeToMono$1(AbstractDataBufferDecoder.java:68)reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:107)reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103)reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287)reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331)reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1505)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onComplete(MonoCollectList.java:123)reactor.core.publisher.FluxJust$WeakScalarSubscription.request(FluxJust.java:101)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onSubscribe(MonoCollectList.java:90)reactor.core.publisher.FluxJust.subscribe(FluxJust.java:70)reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:54)reactor.core.publisher.MonoCollectList.subscribe(MonoCollectList.java:59)reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:44)reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:56)reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)reactor.core.publisher.MonoPeek.subscribe(MonoPeek.java:71)reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103)reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287)reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331)reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1505)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onComplete(MonoCollectList.java:123)reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252)reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:372)reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:196)reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:337)reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:333)reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:453)reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:141)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:191)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323)io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297)io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:677)io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:612)io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:529)io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:491)io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)java.lang.Thread.run(Unknown Source)#3:io.netty.buffer.AdvancedLeakAwareByteBuf.slice(AdvancedLeakAwareByteBuf.java:82)org.springframework.core.io.buffer.NettyDataBuffer.slice(NettyDataBuffer.java:260)org.springframework.core.io.buffer.NettyDataBuffer.slice(NettyDataBuffer.java:42)org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFactory.lambda$null$0(ReadBodyPredicateFactory.java:102)reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:46)reactor.core.publisher.MonoCollectList.subscribe(MonoCollectList.java:59)reactor.core.publisher.MonoFilterFuseable.subscribe(MonoFilterFuseable.java:44)reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:56)reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)reactor.core.publisher.MonoPeek.subscribe(MonoPeek.java:71)reactor.core.publisher.MonoMap.subscribe(MonoMap.java:55)reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103)reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287)reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331)reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1505)reactor.core.publisher.MonoCollectList$MonoBufferAllSubscriber.onComplete(MonoCollectList.java:123)reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252)reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:372)reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:196)reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:337)reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:333)reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:453)reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:141)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:191)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323)io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297)io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:677)io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:612)io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:529)io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:491)io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)java.lang.Thread.run(Unknown Source)

在 #3 中,我發(fā)現(xiàn)了一個眼熟的類,ReadBodyPredicateFactory.java ,還記得最開始的時候使用 readbody 配置么?

這里就是進(jìn)行 cachedRequestBodyObject 的寫入類,

追蹤一下Readbody源碼

/** * This predicate is BETA and may be subject to change in a future release. A * predicate that checks the contents of the request body * @param inClass the class to parse the body to * @param predicate a predicate to check the contents of the body * @param <T> the type the body is parsed to * @return a {@link BooleanSpec} to be used to add logical operators */ public <T> BooleanSpec readBody(Class<T> inClass, Predicate<T> predicate) { return asyncPredicate(getBean(ReadBodyPredicateFactory.class) .applyAsync(c -> c.setPredicate(inClass, predicate))); }

異步調(diào)用的 ReadBodyPredicateFactory.applyAsync() 和 錯誤日志中的

org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFactory.lambda$null$0(ReadBodyPredicateFactory.java:102)

指向方法一致。查看源碼102行:

Flux<DataBuffer> cachedFlux = Flux.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));

此處 Spring Cloud Gateway 通過 dataBuffer.slice 切割出了新的 dataBuffer,但是通過 Netty 的內(nèi)存檢測工具判斷,此處的 dataBuffer 并沒有被回收。

錯誤如下,日志很多容易被忽視。

ERROR io.netty.util.ResourceLeakDetector.reportTracedLeak:317 - LEAK: ByteBuf.release() was not called before it’s garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.

找到問題那就要解決才行,嘗試修改源碼

@Override@SuppressWarnings('unchecked')public AsyncPredicate<ServerWebExchange> applyAsync(Config config) { return exchange -> {Class inClass = config.getInClass();Object cachedBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);Mono<?> modifiedBody;// We can only read the body from the request once, once that// happens if we// try to read the body again an exception will be thrown. The below// if/else// caches the body object as a request attribute in the// ServerWebExchange// so if this filter is run more than once (due to more than one// route// using it) we do not try to read the request body multiple timesif (cachedBody != null) { try {boolean test = config.predicate.test(cachedBody);exchange.getAttributes().put(TEST_ATTRIBUTE, test);return Mono.just(test); } 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(false);} else { // Join all the DataBuffers so we have a single DataBuffer for // the body return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {// Update the retain counts so we can read the body twice,// once to parse into an object// that we can test the predicate against and a second time// when the HTTP client sends// the request downstream// Note: if we end up reading the body twice we will run// into// a problem, but as of right// now there is no good use case for doing thisDataBufferUtils.retain(dataBuffer);// Make a slice for each read so each read has its own// read/write indexesFlux<DataBuffer> cachedFlux = Flux.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) { @Override public Flux<DataBuffer> getBody() {return cachedFlux; }};# 新增如下代碼DataBufferUtils.release(dataBuffer);return ServerRequest.create(exchange.mutate().request(mutatedRequest).build(), messageReaders).bodyToMono(inClass).doOnNext(objectValue -> { exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, objectValue); exchange.getAttributes().put(CACHED_REQUEST_BODY_KEY, cachedFlux);}).map(objectValue -> config.predicate.test(objectValue)); });} };}

Spring Cloud Gateway 在配置的架構(gòu)中,版本為2.1.1,修改以上代碼后,啟動項目測試,問題沒有復(fù)現(xiàn),正常運(yùn)行。

同樣這個問題,也可以選擇升級 Spring Cloud Gateway 版本,在官方2.1.2版本中,此處代碼已被重構(gòu),升級后測試也完全正常。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品国产成人| 四虎4545www国产精品| 日韩久久电影| 色爱av综合网| 亚洲欧洲一区| 在线一区视频| 在线精品福利| 日韩精品一区二区三区中文 | 久久亚洲一区| 香蕉成人久久| 婷婷久久免费视频| 国产精品s色| 老牛影视精品| 亚洲一区观看| 国产亚洲欧美日韩在线观看一区二区 | 日韩av电影一区| 麻豆一区二区三区| 亚洲美女久久精品| 亚洲在线免费| 欧美亚洲国产日韩| 成人免费电影网址| 婷婷精品在线观看| 国产精品蜜月aⅴ在线| 久久人人精品| 日本va欧美va瓶| 亚洲a一区二区三区| 亚洲开心激情| 捆绑调教日本一区二区三区| 欧美日韩国产在线一区| 国产探花在线精品一区二区| 日韩电影免费网站| 日本一区二区中文字幕| 在线成人动漫av| 欧美国产先锋| 中文字幕一区二区三区日韩精品 | 成人午夜精品| 免费日韩一区二区| 日韩在线二区| 国产剧情一区| 亚洲欧美成人综合| 欧美精品日日操| 免费亚洲一区| 日韩毛片一区| 免费观看在线综合色| 久久精品观看| 美女性感视频久久| 日韩和欧美一区二区三区| 亚洲国产一区二区三区在线播放| 欧美国产中文高清| 欧美在线精品一区| 欧美精品中文字幕亚洲专区| 亚洲黑丝一区二区| 97精品国产一区二区三区| 国产精品美女午夜爽爽| 日韩欧美三区| 欧美一区=区| 久久亚洲精品伦理| 欧美精品一线| 91久久黄色| 亚洲自啪免费| 亚洲欧美视频一区二区三区| 狠狠干综合网| 免费日韩av片| 亚洲一区二区小说| 三级在线观看一区二区| 美女日韩在线中文字幕| 久久中文字幕av| 亚洲精品中文字幕乱码| 在线综合欧美| 日韩高清欧美激情| 日韩av在线免费观看不卡| 欧美在线黄色| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 国产精品久久国产愉拍| 久久精品一区二区国产| 麻豆网站免费在线观看| 午夜精品成人av| 99在线精品免费视频九九视| 蜜臀精品久久久久久蜜臀| 日韩午夜免费| 欧美在线黄色| 91tv亚洲精品香蕉国产一区| 99久精品视频在线观看视频| 亚洲综合不卡| 欧美a一区二区| 国产v日韩v欧美v| 中文字幕亚洲精品乱码| 国产精品久久久久久妇女| 高清日韩欧美| 欧美专区18| 国产一区二区精品久| 日韩成人综合| 久久国内精品视频| 欧美成人精品| 国产日韩欧美一区在线| 久久精品高清| 日韩精品视频网站| 99精品在线观看| 国产精品久久乐| 一本一道久久a久久精品蜜桃| 亚洲精品极品| 亚洲电影在线| 精品国产一区二区三区2021| 喷白浆一区二区| 999久久久免费精品国产| 国产精品免费不| 欧美高清一区| 精品不卡一区| 日韩国产欧美视频| 日韩在线播放一区二区| 久久精品国内一区二区三区水蜜桃| 国产精品久久久久久久免费软件| 日韩一级欧洲| 婷婷激情久久| 久久久精品网| 黄色欧美在线| 国产一区二区三区91| 国产精品久久久久久久免费软件 | av亚洲免费| 涩涩av在线| 成人在线黄色| 精品国产精品国产偷麻豆| 日本午夜精品| 欧美午夜三级| 97se亚洲| 国产三级一区| 国产精品黄色片| 国产精品分类| 久久在线91| 丝袜美腿诱惑一区二区三区| 亚洲人成在线网站| 日韩免费av| 怡红院精品视频在线观看极品| 日本综合字幕| 99久久亚洲精品蜜臀| 黄色av一区| 中文字幕av一区二区三区四区| 蜜桃免费网站一区二区三区| 亚洲精品三级| 国产精品成人一区二区网站软件| 久久精品国产精品亚洲毛片| 成人午夜网址| 91精品高清| 亚洲精品高潮| 国产精品美女午夜爽爽| 理论片午夜视频在线观看| 欧美在线资源| 国产情侣一区| 国产一二在线播放| 久久中文字幕av一区二区不卡| 视频在线在亚洲| 久久三级毛片| 首页国产欧美日韩丝袜| 国产亚洲欧美日韩在线观看一区二区 | 国产一卡不卡| 另类中文字幕国产精品| 欧美影院三区| 欧美亚洲tv| 欧美日韩高清| 久久69成人| 久久av一区| 欧美日韩99| 国产一区导航| 日韩免费久久| 国产精品毛片久久久| 国产视频一区三区| 日韩一区电影| 精品一区二区三区免费看| 一区在线免费| 久久久国产精品一区二区中文| 日韩av电影一区| 亚洲欧美久久久| 欧美综合另类| 91av亚洲| 久久一区亚洲| 国产欧美日韩影院| 午夜一级在线看亚洲| 久久久水蜜桃av免费网站| 久久久久久亚洲精品美女| 亚久久调教视频| 中文在线一区| 天堂网在线观看国产精品| а√天堂8资源中文在线| 国产高清亚洲| 国产精品任我爽爆在线播放| 水蜜桃久久夜色精品一区的特点| 亚洲天堂久久| 午夜日韩在线| 亚洲欧美视频| 亚洲精品伊人| 91亚洲无吗| 少妇精品在线| 亚洲在线久久| 老牛影视一区二区三区| 丝袜脚交一区二区| 色8久久久久| 国产激情综合| 日本а中文在线天堂| 999国产精品视频| 国产精品美女久久久|