Sentinel Make default JUL-based logging asynchronous

ycl3bljg  于 2021-11-29  发布在  Java
关注(0)|答案(2)|浏览(298)

Reactor blockhound detected blocking calls where RecordLog flushes logs with sync IO.

weblux(spring cloud gateway)下应该避免同步IO处理的

reactor.blockhound.BlockingOperationError: Blocking call! java.io.FileOutputStream#writeBytes
	at java.io.FileOutputStream.writeBytes(FileOutputStream.java)
	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
	|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
	|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
	|_ checkpoint ⇢ HTTP POST "/hello/yyy?token=sadasdas" [ExceptionHandlingWebHandler]
Stack trace:
		at java.io.FileOutputStream.writeBytes(FileOutputStream.java)
		at java.io.FileOutputStream.write(FileOutputStream.java:326)
		at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
		at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
		at java.io.PrintStream.write(PrintStream.java:482)
		at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
		at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
		at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
		at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
		at java.io.PrintStream.write(PrintStream.java:527)
		at java.io.PrintStream.print(PrintStream.java:669)
		at java.io.PrintStream.println(PrintStream.java:806)
		at com.alibaba.csp.sentinel.log.LogBase.<clinit>(LogBase.java:72)
		at com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager$GatewayRulePropertyListener.applyToConvertedParamMap(GatewayRuleManager.java:214)
		at com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager$GatewayRulePropertyListener.applyGatewayRuleInternal(GatewayRuleManager.java:148)
		at com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager$GatewayRulePropertyListener.configLoad(GatewayRuleManager.java:124)
		at com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager$GatewayRulePropertyListener.configLoad(GatewayRuleManager.java:114)
		at com.alibaba.csp.sentinel.property.DynamicSentinelProperty.addListener(DynamicSentinelProperty.java:40)
		at com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager.<clinit>(GatewayRuleManager.java:57)
		at com.alibaba.csp.sentinel.adapter.gateway.common.param.GatewayParamParser.parseParameterFor(GatewayParamParser.java:58)
		at cn.sunline.edsp.gateway.server.filters.SentinelGatewayFilter.filter(SentinelGatewayFilter.java:71)
		at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:138)
		at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44)
		at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.lambda$filter$0(FilteringWebHandler.java:118)
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153)
		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)
		at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)
		at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103)
		at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287)
		at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:330)
		at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1712)
		at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:160)
		at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)
		at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252)
		at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)
		at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:421)
		at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:211)
		at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:369)
		at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:367)
		at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:489)
		at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:90)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
		at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:214)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
		at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
		at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:321)
		at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295)
		at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
		at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
		at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
		at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
		at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
		at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
		at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
		at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
		at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
		at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
		at java.lang.Thread.run(Thread.java:748)
tkqqtvp1

tkqqtvp11#

We could indeed make default JUL-based logging implementation asynchronous when flushing logs. Contributions are welcomed!

pgpifvop

pgpifvop2#

After reading the source code, I found that JUL writes files through OutputStreamWriter. Do I need to use NiO to implement an asynchronous log file writing class? such as AsynchronousFileChannel

相关问题