Azure Spring Cloud 是什么?
借助 Azure Spring Cloud,可以輕松地將 Spring Boot 微服務應用程序部署到 Azure,不需更改任何代碼。 該服務管理 Spring Cloud 應用程序的基礎結構,因此開發人員可以專注於其代碼。 Azure Spring Cloud 可以通過以下方法提供生命周期管理:綜合性監視和診斷、配置管理、服務發現、CI/CD 集成、藍綠部署等。 Link: https://docs.azure.cn/zh-cn/spring-cloud/overview
問題描述
在本地運行正常的Spring Cloud項目,部署在Azure Spring Cloud服務后,在日志中,發現大量的null pointer exception
java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at io.lettuce.core.protocol.CommandHandler.write(CommandHandler.java:378) at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764) at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:808) at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1025) at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:294) at io.lettuce.core.protocol.DefaultEndpoint.channelWriteAndFlush(DefaultEndpoint.java:392) at io.lettuce.core.protocol.DefaultEndpoint.writeToChannelAndFlush(DefaultEndpoint.java:332) at io.lettuce.core.protocol.DefaultEndpoint.write(DefaultEndpoint.java:162) at io.lettuce.core.protocol.DefaultEndpoint$RetryListener.requeueCommands(DefaultEndpoint.java:1002) at io.lettuce.core.protocol.DefaultEndpoint$RetryListener.lambda$potentiallyRequeueCommands$0(DefaultEndpoint.java:989) at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98) at io.netty.util.concurrent.PromiseTask.run(PromiseTask.java:106) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
問題解決
根據在Github和stackoverflow中查看到的信息,判斷這是一個和sleuth版本相關,在新的版本中,默認啟用了redis配置。通過 spring.sleuth.redis.enabled=false 來關閉默認配置, Null Point Exception問題解決。
StackOverflow :
I use spring-session-data-redis to manage sessions. It will get session data from redis before every request. But it throws a NPE when get session from redis. And if I remove spring-cloud-starter-sleuth dependency, it won't happend.
springboot version: 2.3.8.RELEASE
springcloud version: Hoxton.SR10
Here is the exception information:
java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.lettuce.core.protocol.CommandHandler.write(CommandHandler.java:378) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:808) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1025) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:294) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.lettuce.core.protocol.DefaultEndpoint.channelWriteAndFlush(DefaultEndpoint.java:392) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.lettuce.core.protocol.DefaultEndpoint.writeToChannelAndFlush(DefaultEndpoint.java:332) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.lettuce.core.protocol.DefaultEndpoint.write(DefaultEndpoint.java:162) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.lettuce.core.protocol.DefaultEndpoint$RetryListener.requeueCommands(DefaultEndpoint.java:1002) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.lettuce.core.protocol.DefaultEndpoint$RetryListener.lambda$potentiallyRequeueCommands$0(DefaultEndpoint.java:989) ~[lettuce-core-5.3.6.RELEASE.jar:5.3.6.RELEASE] at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.concurrent.PromiseTask.run(PromiseTask.java:106) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:164) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497) [netty-transport-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.58.Final.jar:4.1.58.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.58.Final.jar:4.1.58.Final]
Answer:
I have resolved this problem. It seems that there are some bugs in this sleuth version. I compare this new version with the old version we used, the old version sleuth doesn't intercept the redis request, but this new version will. If I disable this configuration, it won't happen. I use 'spring.sleuth.redis.enabled=false' to disable redis sleuth configuration. It is enabled by default.
GitHub: https://githubmemory.com/repo/spring-cloud/spring-cloud-sleuth/issues/1992