【记录一个问题排查】

场景

有2台服务器,基于netty通信,使用google的protobuf序列化。A服务器向B服务器发送一个序列化对象

问题

A服务器发送前,打印的对象属性,其中有个isLoading=0
B服务器接受到对象,打印出来的isLoading=2
其中该对象的isLoading默认值是2

初步分析

造成这种现象的情况,肯定是中间某一步出现了问题,导致该对象使用了默认值
排查代码,发现A服务器不可能修改对象属性,那问题必然出现在B服务器
排查B服务器,搜索了所有set操作,没有找到修改的地方

进一步寻找线索

利用Arthas动态添加日志发现在protobuf转化的时候,属性就已经变成2了
但是还是没有头绪,是protobuf的问题呢还是netty的问题呢?

祭出终极杀器

最终决定,利用远程 debug查看到底是哪里出了问题。随着一步步debug,最终找到了问题
是在使用protobuf的时候,有一步时要利用protobuf的工具转成String 类型的json串,在这一步关键属性消失了。
JsonFormat.printer().print(sourceMessage)
这里使用的时printer没有把默认值也转换成json,所以最终导致了反转对象的时候,出现了问题
new Gson().fromJson(json, targetClass);这一步使用的targetClass指定的isLoading默认是2,所以转出来的对象属性就不是0了

解决

解决就很简单了,设置一下可以转换默认值即可
JsonFormat.printer().includingDefaultValueFields().print(sourceMessage);

总结

在解决这个问题的路上花了挺多时间的。
一是对arthas不熟悉,无法很好的使用arthas这个工具。
第二就是对第三方框架不够了解的情况下很容易就踩坑
第三就是不断在猜测到底哪里出了问题,没有实际去测试。
第四是使用netty框架的情况,不会用netty,无法模拟端到端的一个通讯

posted @ 2021-12-22 15:40  自律のalive  阅读(32)  评论(0编辑  收藏  举报