java.lang.OutOfMemory使用Spring Boot WebFlux Starter的错误



我已经创建了2个微服务,包括Spring Boot(版本1.5.1发布),Spring Cloud(Edgware.SR3),Spring Cloud Starter Config(版本1.4.3发布)和Netflix的Eureka命名服务器(Spring Cloud Starter Netflix Eureka Client/Server 1.4.4 RELEASE):

  1. 尤里卡服务器(用于注册微服务的服务)
  2. 尤里卡客户端(用于保存/更新操作的数据库服务)

尤里卡客户端是一个简单的Restful服务,具有单个@PostMapping注释方法,该方法接受一个相当大的对象作为参数(@RequestBody MyObject object)。

尤里卡客户端成功地向尤里卡服务器注册了自己。

然后在SpringBoot Webflux的帮助下,我尝试在Spring 5中引入的类WebClient的帮助下访问我的尤里卡客户端,这是AsyncRestTemplate类的即兴创作。我做如下的事情:

WebClient webClient = WebClient.create();
reactor.core.publisher.Mono result = (Mono) webClient.post()
.uri("http://localhost:8080/eureka-client")
.body(BodyInserters.fromObject(//myComplexObject here))
.retrieve()
.bodyToMono(String.class);
result.subscribe();

在调试时,我发现在上述代码的最后一行之后我收到 OOM 异常。

io.netty.handler.codec.EncoderException: java.lang.OutOfMemoryError

下面的全栈跟踪:

[reactor-http-nio-4] WARN  io.netty.util.concurrent.AbstractEventExecutor  - A task raised an exception. Task: reactor.ipc.netty.channel.ContextHandler$$Lambda$401/11401686@10ae5a2
reactor.core.Exceptions$ErrorCallbackNotImplemented: io.netty.handler.codec.EncoderException: java.lang.OutOfMemoryError
Caused by: io.netty.handler.codec.EncoderException: java.lang.OutOfMemoryError
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:106)
at io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:348)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:816)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:723)
at reactor.ipc.netty.channel.ChannelOperationsHandler.doWrite(ChannelOperationsHandler.java:291)
at reactor.ipc.netty.channel.ChannelOperationsHandler.drain(ChannelOperationsHandler.java:465)
at reactor.ipc.netty.channel.ChannelOperationsHandler.flush(ChannelOperationsHandler.java:191)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:802)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:831)
at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1051)
at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300)
at reactor.ipc.netty.http.HttpOperations.lambda$then$0(HttpOperations.java:135)
at reactor.ipc.netty.FutureMono.lambda$deferFuture$0(FutureMono.java:68)
at reactor.ipc.netty.FutureMono$DeferredFutureMono.subscribe(FutureMono.java:134)
at reactor.core.publisher.Mono.subscribe(Mono.java:3008)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:167)
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
at reactor.core.publisher.Mono.subscribe(Mono.java:3008)
at reactor.core.publisher.FluxConcatIterable$ConcatIterableSubscriber.onComplete(FluxConcatIterable.java:141)
at reactor.core.publisher.FluxConcatIterable.subscribe(FluxConcatIterable.java:60)
at reactor.core.publisher.MonoSourceFlux.subscribe(MonoSourceFlux.java:47)
at reactor.ipc.netty.channel.ChannelOperations.applyHandler(ChannelOperations.java:380)
at reactor.ipc.netty.http.client.HttpClientOperations.onHandlerStart(HttpClientOperations.java:501)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.OutOfMemoryError
at sun.misc.Unsafe.allocateMemory(Native Method)
at io.netty.util.internal.PlatformDependent0.allocateDirectNoCleaner(PlatformDependent0.java:430)
at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:596)
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.buffer(AbstractByteBufAllocator.java:113)
at io.netty.handler.codec.http.HttpObjectEncoder.encode(HttpObjectEncoder.java:92)
at io.netty.handler.codec.http.HttpClientCodec$Encoder.encode(HttpClientCodec.java:167)
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:88)
... 32 more

我的类路径中有杰克逊库,并依靠 spring 来序列化我的复杂对象,同时将其传递给 Restful 服务。我不确定是什么原因造成的。请指点什么?

在 Java 执行路径中添加此

内容-Dio.netty.noPreferDirect=true

最新更新