记录一次gateway HandlerStrategies.withDefaults().messageReaders() 导致的内存炸裂的问题

news2024/9/27 9:20:41

背景

年前出现了一次内存炸裂的生产事故。导致其他请求无法请求通过。
[boundedElastic-55] [Loggers.java:314]:Scheduler worker in group main failed with an uncaught exception

[TID:] 2023-01-18 10:40:33.189 [INFO] [boundedElastic-55] [AccessTokenGatewayFilterFactory.java:223]:ReqId:[req167400963317915899035994841384],执行时间:[3]ms
[TID:] 2023-01-18 10:40:35.280 [ERROR] [boundedElastic-55] [Loggers.java:314]:Scheduler worker in group main failed with an uncaught exception

java.lang.OutOfMemoryError: unable to create new native thread
	at java.lang.Thread.start0(Native Method) ~[na:1.8.0_342]
	at java.lang.Thread.start(Thread.java:719) ~[na:1.8.0_342]
	at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957) ~[na:1.8.0_342]
	at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1603) ~[na:1.8.0_342]
	at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:334) ~[na:1.8.0_342]
	at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:573) ~[na:1.8.0_342]
	at reactor.core.scheduler.BoundedElasticScheduler.start(BoundedElasticScheduler.java:175) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.scheduler.Schedulers.newBoundedElastic(Schedulers.java:498) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.scheduler.Schedulers.newBoundedElastic(Schedulers.java:454) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at org.springframework.http.codec.multipart.DefaultPartHttpMessageReader.<init>(DefaultPartHttpMessageReader.java:77) ~[spring-web-5.3.2.jar!/:5.3.2]
	at org.springframework.http.codec.support.ServerDefaultCodecsImpl.extendTypedReaders(ServerDefaultCodecsImpl.java:72) ~[spring-web-5.3.2.jar!/:5.3.2]
	at org.springframework.http.codec.support.BaseDefaultCodecs.getTypedReaders(BaseDefaultCodecs.java:275) ~[spring-web-5.3.2.jar!/:5.3.2]
	at org.springframework.http.codec.support.BaseCodecConfigurer.getReaders(BaseCodecConfigurer.java:98) ~[spring-web-5.3.2.jar!/:5.3.2]
	at org.springframework.http.codec.support.DefaultServerCodecConfigurer.getReaders(DefaultServerCodecConfigurer.java:27) ~[spring-web-5.3.2.jar!/:5.3.2]
	at org.springframework.web.reactive.function.server.DefaultHandlerStrategiesBuilder.build(DefaultHandlerStrategiesBuilder.java:101) ~[spring-webflux-5.3.2.jar!/:5.3.2]
	at org.springframework.web.reactive.function.server.HandlerStrategies.withDefaults(HandlerStrategies.java:89) ~[spring-webflux-5.3.2.jar!/:5.3.2]
	at com.oneworld.gateway.filter.SignatureCacheBodyParamsFilter.getHttpMessageReadersWithMaxInMemorySize(SignatureCacheBodyParamsFilter.java:53) ~[classes!/:1.3.0-SNAPSHOT]
	at com.oneworld.gateway.filter.SignatureCacheBodyParamsFilter.filter(SignatureCacheBodyParamsFilter.java:41) ~[classes!/:1.3.0-SNAPSHOT]
	at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:137) ~[spring-cloud-gateway-server-3.0.0.jar!/:3.0.0]
	at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44) ~[spring-cloud-gateway-server-3.0.0.jar!/:3.0.0]
	at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.lambda$filter$0(FilteringWebHandler.java:117) ~[spring-cloud-gateway-server-3.0.0.jar!/:3.0.0]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:173) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:281) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:860) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1784) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:281) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:860) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1784) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFilterWhen$MonoFilterWhenMain.onNext(MonoFilterWhen.java:149) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2346) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFilterWhen$MonoFilterWhenMain.onSubscribe(MonoFilterWhen.java:112) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:448) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onNext(FluxConcatMap.java:250) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDematerialize$DematerializeSubscriber.onNext(FluxDematerialize.java:98) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDematerialize$DematerializeSubscriber.onNext(FluxDematerialize.java:44) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:270) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:228) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDematerialize$DematerializeSubscriber.request(FluxDematerialize.java:127) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:235) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDematerialize$DematerializeSubscriber.onSubscribe(FluxDematerialize.java:77) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:62) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:54) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:448) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:218) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:148) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:99) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:281) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:860) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1784) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:854) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmitScalar(FluxFlatMap.java:487) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:420) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:270) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:228) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:370) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:448) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:218) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:173) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:84) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2348) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2154) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2028) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:845) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:607) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:587) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:464) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:292) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:228) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:370) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1784) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:107) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:269) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1785) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:328) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onNext(MonoCacheTime.java:345) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:251) ~[reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) [reactor-core-3.4.1.jar!/:3.4.1]
	at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) [reactor-core-3.4.1.jar!/:3.4.1]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_342]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_342]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_342]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_342]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_342]
	at java.lang.Thread.run(Thread.java:750) ~[na:1.8.0_342]

根据调用栈找到最先的代码片段
目的是为了保证在gateway某次请求不限制body大小的问题,需要从网关的策略类中拿到一些reader,并且修改当前read的读取字节的大小。
本来是一个比较简单问题。

List<HttpMessageReader<?>> HTTP_MESSAGE_READERS = HandlerStrategies.withDefaults().messageReaders();

反而在gateway使用过程中,频繁发生

java.lang.OutOfMemoryError: unable to create new native thread

根据最上一条包含com【本公司代码前缀】,找到定位到这句话。
这句本身,没有问题,但是其实是一个坑,在HandlerStrategies.withDefaults()获取默认策略过程中,
会在底层调用 编解码配置类中的readers。
其实拿这个东西,问题不大,基本上都是单例模式的拿。也造成不了内存溢出。

而是在拿的过程中,即在初始化的时候一直在new东西。
这就问题比较大了
根据调用链,我们找到

BaseDefaultCodecs: 
final List<HttpMessageReader<?>> getTypedReaders() {
		if (!this.registerDefaults) {
			return Collections.emptyList();
		}
		List<HttpMessageReader<?>> readers = new ArrayList<>();
		addCodec(readers, new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
		addCodec(readers, new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
		addCodec(readers, new DecoderHttpMessageReader<>(new DataBufferDecoder()));
		if (nettyByteBufPresent) {
			addCodec(readers, new DecoderHttpMessageReader<>(new NettyByteBufDecoder()));
		}
		addCodec(readers, new ResourceHttpMessageReader(new ResourceDecoder()));
		addCodec(readers, new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly()));
		if (protobufPresent) {
			addCodec(readers, new DecoderHttpMessageReader<>(this.protobufDecoder != null ?
					(ProtobufDecoder) this.protobufDecoder : new ProtobufDecoder()));
		}
		addCodec(readers, new FormHttpMessageReader());

		// client vs server..
		extendTypedReaders(readers);

		return readers;
	}

中的 extendTypedReaders方法。

class ServerDefaultCodecsImpl:
	protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) {
		if (this.multipartReader != null) {
			addCodec(typedReaders, this.multipartReader);
			return;
		}
		DefaultPartHttpMessageReader partReader = new DefaultPartHttpMessageReader();
		addCodec(typedReaders, partReader);
		addCodec(typedReaders, new MultipartHttpMessageReader(partReader));
	}

此时就会new DefaultPartHttpMessageReader();

class DefaultPartHttpMessageReader: 
	private Scheduler blockingOperationScheduler = Schedulers.newBoundedElastic(Schedulers.DEFAULT_BOUNDED_ELASTIC_SIZE,
			Schedulers.DEFAULT_BOUNDED_ELASTIC_QUEUESIZE, IDENTIFIER, 60, true);

最后可以看到这个类对象内部维护了一个内部对象变量,这个变量就是创建一个线程。
用完之后不会释放也没有释放的入口
以上就导致了内存溢出。

解决方案

在filter创建过程中,利用@SmartInitializingSingleton注解,初始化一个对象,这样不用每次调用都创建一个新的对象。全局维护一个

SmartInitializingSingleton 生命周期在spring bean容器初始化之后,但是在结束spring完成之前的一步小操作
1、 此时也不用担心应用在调用该类的时候造成空指针问题
2、也确保调用的方法中的实例对象都已经被初始了。

在这里插入图片描述
上图就是优化之后的流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/170363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Arduino基础学习——meArm(太极创客第二部分)

面包板电源模块为机器臂单独供电&#xff0c;机器臂本身有四个小电机驱动作用&#xff0c;如果单独靠arduino来为这四个小电机供电&#xff0c;机器臂可能不会稳定工作&#xff0c;将会抖动。 机械臂的四个动作主要靠四个电机来控制&#xff0c;这四个电机主要连接在我们的ard…

云端IDE系列教程4:TitanIDE + Typora = 鱼和熊掌

概述 目前&#xff0c;大部分技术人员使用 Markdown 编写技术文档已经成了日常工作的一部分&#xff0c;现在市场上也有各种各样的文字编辑工具&#xff1a;石墨文档、有道云笔记、语雀、金山文档、腾讯文档、Google文档&#xff0c;WPS、Office、Typora等。但在云原生时代&am…

vue3学习笔记(总)——ts+组合式API(setup语法糖)

文章目录1. ref全家桶1.1 ref()1.2 isRef()以及isProxy()1.3 shallowRef()1.4 triggerRef()1.5 customRef()1.6 unref()2. reactive全家桶2.1 reactive()2.2 readonly()2.3 shallowReactive() 和 shallowReadonly()3. to系列全家桶3.1 toRef()3.2 toRefs()3.3 toRaw()4. comput…

【年度总结】回看2022,展望2023,做更好的自己

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

Mac 下ZooKeeper安装和使

Mac 下ZooKeeper安装和使用 Apache ZooKeeper分布式协调系统是构建分布式应用程序的高性能服务。 1.下载ZooKeeper 环境要求&#xff1a;ZooKeeper服务器是用Java创建的&#xff0c;它运行在JVM之上。需要安装JDK 7或更高版本。 https://zookeeper.apache.org/releases.html …

1.3 PCIe——硬件实现架构

PCIe的设计可以分为controller和PHY&#xff0c;整体设计较为复杂&#xff0c;一般可向IP厂商定制设计&#xff0c;controller和PHY模块的接口是PIPE接口 一、一般实现架构 1.1 PCIE controller 控制器逻辑包含了IP的host设计&#xff0c;以及PCIe协议中所规定的事务层、数…

AirServer电脑投屏软件免费版使用及切换中文教程

AirServer是由App Dynamic打造的一款投屏软件。AirServer是适用于Mac和Windows的先进的屏幕镜像接收器。可以将手机设备&#xff0c;如iPhone、iPad、安卓上的屏幕投送到电脑屏幕上。特别我们日常开会要给客户演示手机上的操作时&#xff0c;投屏就显得非常专业。当然&#xff…

关于java位移运算的一点讨论

框架乱飞的年代&#xff0c;时常还得往框架源码里看&#xff0c;对内在原理没点理解&#xff0c;人家就会认为你不太行。平时开发你可能没咋用过位移运算&#xff0c;但往源码里一看&#xff0c;就时常能看到它。我也是看着看着&#xff0c;突然仔细一琢磨&#xff0c;又不由得…

【机器学习 - 4】:线性回归算法

文章目录线性回归线性回归的理解损失函数简单线性回归封装线性回归算法线性回归算法在sklearn中调用线性回归算法向量化运算线性回归模型中的误差均方误差 MSE均方根误差平均绝对误差调用sklearn中的均方根误差和平均绝对误差函数R squared error &#xff08;常用&#xff09;…

结构光相机国产、非国产统计参数对比分析

结构光相机国产、非国产统计参数对比分析 1. Kinect v1 Kinect v1深度相机拥有一个RGB彩色摄像头&#xff0c;一个红外线CMOS摄像机和一个红外发射器。相机的红外线CMOS摄像机和红外发射器以左右水平的方式分布。该相机采用的是以结构光为基础进行改进后的光编码&#xff08;…

【SpringCloud16】SpringCloud Sieuth分布式请求链路跟踪

1.概述 1.1 为什么会出现这个技术&#xff1f; 问题&#xff1a; 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果&#xff0c;每一个前段请求都会形成一条复杂的分布式服务调用链路&#xff0c;链路中…

Linux服务器离线安装Gitlab

1、下载 1.1、网址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 1.2、选择版本 2、安装 2.1、将安装包上传到服务器 2.2、检查相关依赖是否安装 使用命令 rpm -qa | grep -i &#xff08;要查看的依赖名&#xff09;&#xff1b;如果安装了&#…

OpenAI DALL·E 绘画机器人

快过年了&#xff0c;在公司也没啥任务&#xff0c;索性尝试使用OpenAI的DALLE生成一些好玩的图片。 OpenAI DALLE 官方介绍&#xff1a; DALLE 是一种由 OpenAI 开发的大型语言模型&#xff0c;其能够通过生成图像和文本来完成各种任务。其名称来源于绘画机器人 WALLE 和艺术家…

2023年准备报考软考,考哪个?

一般建议从软考中级考试考&#xff0c;科目多&#xff0c;难度也不大&#xff01;关于中级科目。计算机软件类包括&#xff1a;软件评测师、软件设计师、软件过程能力评估师。计算机网络类包括&#xff1a;网络工程师。计算机应用技术类包括&#xff1a;多媒体应用设计师、嵌入…

DBCO-PEG-OPSS_OPSS-PEG-DBCO_二苯并环辛烯PEG巯基吡啶

DBCO 试剂是一类点击化学标记试剂&#xff0c;含有非常活泼的 DBCO&#xff08;&#xff08;二苯并环辛炔&#xff09;基团&#xff0c;DBCO 试剂可以通过无铜点击化学与叠氮化物标记的分子或生物分子发生反应。DBCO 点击化学可以在水性缓冲液中运行&#xff0c;也可以在有机溶…

机器学习知识总结 —— 16.如何实现一个简单的SVM算法

文章目录创建具有特征的二维数据实现SVM算法线性核函数梯度下降和损失函数训练实验效果总结在前面的章节里&#xff0c;已经简要的介绍了SVM算法的工作原理&#xff0c;现在在这篇文章里&#xff0c;我们来看看SVM算法的一些简单实现。 创建具有特征的二维数据 一般来说&…

【闪电侠学netty】第8章 客户端与服务端通信协议编解码

【Netty】读书笔记 - 跟闪电侠学 1. 内容概要 1.1 总结 1.1.1 编码与解码定义 编码&#xff1a;把java对象根据协议封装成二进制数据包的过程 解码&#xff1a;从二进制数据包中解析出Java对象的过程 1.1.2 设计了如下几个类 文件名类型描述Serializerinterface 作用&#…

MacOS Docker 安装和运行原理

本文讲述主要是基于Mac电脑安装教程&#xff0c;使用的是homebrew安装&#xff0c;未安装homebrew的请先自行安装下 一、使用 Homebrew 安装 macOS 我们可以使用 Homebrew 来安装 Docker。Homebrew 的 Cask 已经支持 Docker for Mac&#xff0c;因此可以很方便的使用 Homebrew…

【代码实验】CNN实验——利用Imagenet子集训练分类网络(AlexNet/ResNet)

文章目录前言一、数据准备二、训练三、结果前言 Imagenet是计算机视觉的经典分类比赛&#xff0c;但是Imagenet数据集本身太大了&#xff0c;我们穷学生没有这么大的算力&#xff0c;2016年google DeepMind团队从Imagnet数据集中抽取的一小部分&#xff08;大小约3GB&#xff…

DBCO-PEG-Methacrylate_DBCO-PEG-MA_二苯并环辛炔-PEG-甲基丙烯酸酯

一、试剂基团反应特点&#xff08;Reagent group reaction characteristics&#xff09;&#xff1a;DBCO&#xff08;二苯并环辛炔&#xff09;是一种环炔烃&#xff0c;可以通过在水溶液中通过应变促进的1,3-偶极环加成反应与叠氮化物反应&#xff0c;这种生物正交反应也称为…