Redisson 3.16.2生产环境报Unsupported protocol version 0错误是什么原因?
报错含义解释
Unsupported protocol version 0 是JBoss Marshalling序列化框架抛出的反序列化异常:
JBoss Marshalling的River协议在序列化后会在二进制数据开头写入固定的协议版本标识(合法值范围为1-4),反序列化时会优先读取该标识位做校验,读到0值说明当前拿到的二进制数据并非合法的River协议序列化结果,无法正常反序列化。
你提供的完整异常堆栈如下:
java.io.IOException: Unsupported protocol version 0 at org.jboss.marshalling.river.RiverUnmarshaller.start(RiverUnmarshaller.java:1375) at org.redisson.codec.MarshallingCodec.lambda$new$0(MarshallingCodec.java:145) at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:366) at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:183) at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:122) at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:107) at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508) at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) 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:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) 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)
生产/测试环境表现不一致的常见原因
- 生产Redis中的存量数据由其他序列化器(非MarshallingCodec)写入:比如旧版本应用、其他业务服务写入数据时用的是Jackson、Kryo等序列化器,用MarshallingCodec反序列化时自然无法识别协议头
- 两套环境的Redisson序列化配置不一致:测试环境未显式配置codec,用的是默认序列化策略,生产环境错误配置为MarshallingCodec,导致读测试环境新写入的兼容数据无异常,读生产存量数据时报错
- 生产环境网络异常:存在TCP拆包粘包问题,Netty解码时拿到的是不完整的数据包,开头位刚好为0被识别为非法版本号
- 生产Redis开启了SSL加密,而Redisson客户端未配置对应SSL参数,拿到的加密二进制流不符合Marshalling协议格式
排查修复方案
- 对比生产和测试环境的Redisson配置,确认
codec参数是否完全一致,执行RedissonConfig.getCodec()打印序列化器实现类做校验 - 取出生产Redis中报错对应Key的原始二进制值,合法的Marshalling序列化结果前四位为
0xAC 0xED 0x00 0x05,不符合该特征就说明数据来源不匹配 - 临时将生产环境的序列化器替换为和测试环境完全相同的实现,验证报错是否消失
- 对齐生产和测试环境的Redis连接SSL配置,避免加密流解析异常
内容的提问来源于stack exchange,提问作者İlkay Gunel
相关产品推荐
相关产品推荐

