debbo最终打印结果显示_dubbo服务provider方打印警告日志,getDeserializer - Hessian/Burla 'xxx' is an unknown class...

2018-09-12 16:16:44 WARN [New I/O worker #1] SerializerFactory.java:652 getDeserializer - Hessian/Burlap: 'com.xxx.xxxBolt$1' is an unknown class in sun.misc.Launcher$AppClassLoader@a2c6f70

今天下午4点过商品组同事反馈,线上他们那边有个dubbo服务A(provider)打印了很多WARN日志让看看。

这个日志是在dubbo的hessian-lite模块下SerializerFactory类,Deserializer getDeserializer(String type)方法中打印的:

看名称大概是获取反序列化类。在服务A中接口方法是能正常调用的,不影响业务。但是该方法调用很频繁,大量这样的WARN日志显然不好。

其实这个问题之前遇到过,当时是dubbo的provider方接口有升级,方法入参vo有变动,consumer端依赖了provider放的api interface包,没有及时重新构建发布。

不过看这次日志打印很奇怪,'com.xxx.XxxBolt$1' is an unknown class,XxxBolt是我们这边一个storm拓扑(比如拓扑T)中的一个bolt名称,在该bolt中调用了服务A的一个接口;

服务A依赖了包B,B下面有个枚举类C;

该接口方法签名为 Map 方法名(Long xxId, Set xxSet);

检查XxxBolt中调接口的代码,

调用如下:

Long xxId = ...;

Set xxSet = new HashSet{{

add(枚举C.枚举1,xxx);

add(枚举C.枚举2,xxx);

...

}}

Map result = 方法名(Long xxId, Set xxSet);

看代码中并没有把XxxBolt作为参数传递,而且服务A没有依赖storm拓扑的项目,怎么日志里会打印出XxxBolt的类名呢?

这个问题先放着,我们先回想了一下:服务A上周有过改动构建发布,storm的拓扑T的XxxBolt也有改动并发布,不过可以确定的是这段调用代码,包括请求参数,是没有改动的;

刚才提到,服务A依赖了包B,包B也有改动;那么拓扑T是否是在服务A、包C构建之后构建发布的呢?(虽然记忆中是按的这个顺序)

在jenkins上查看构建记录,包B是9月5号上午11点构建的,服务A是下午4点构建发布的,我们这边的拓扑T是下午5点以后构建发布的;

在storm UI上去看拓扑的Uptime,已启动了5天多10多个小时,推算下时间,也证明拓扑T是构建后重启的;

综上2点,说明拓扑T的依赖(A和B)都是最新的,应该不存在provider和consumer枚举C类不一致的问题。

跟同事沟通确定这点后都有些疑惑。尝试把拓扑T构建打包后的jar下到本地,解压出来看class文件,发下XxxBolt类所在包下,不仅有XxxBolt.class,还多了一个XxxBolt$1.class;

再回头看日志'com.xxx.XxxBolt$1' is an unknown class,这时才注意到日志里说找不到类的名称,XxxBolt后面多了$1,之前看漏了- -!

想起java编译生成class文件,如果定义了内部类会产生xxx$xxx的class文件;

可记得XxxBolt类里面并没有定义内部类啊,翻看一遍代码确实没有。

用反编译工具打开XxxBolt$1.class:

import com.xxx.枚举B;

import java.util.HashSet;

class 1 extends HashSet

{

}

类名是1,这样XxxBolt$1名称解释得通,但它是哪里产生的呢?

刚才枚举B已确定是最新的,于是我们把目光锁定在了这个HashSet的构造上

Set xxSet = new HashSet{{

add(枚举C.枚举1,xxx);

add(枚举C.枚举2,xxx);

...

}}

这里使用了快捷的初始化数据语法,即在{{}}里用add的方式;

尝试把XxxBolt代码里的某个Map xxx = new HashMap也用这种写法,重新编译发现生成了XxxBolt$2.class,反编译打开是class 2 extends HashMap<>...

那么问题找到了,拉分支把这段代码修改下:

Set xxSet = new HashSet();

xxSet.add(枚举C.枚举1, xxx);

xxSet.add(枚举C.枚举2, xxx);

...

用普通的初始化方式,先new好,在用对象调add方法。

重新编译就只有XxxBolt.class了。

依次合并代码至主干后,重新构建发布并重启拓扑T,再观察服务A中已没有这个警告日志了。

问题解决:)

-------------------------------------------------------------------------------------------------------------------------------------------------

总结:

dubbo服务provider和consumer中入参要保持一致,入参vo有类型或结构变动,consumer端需要跟着provider构建,依赖最新的包;

HashSet、HashMap用快捷初始化语法时,编译会产生内部类,以Xxx$1这种命名方式,在dubbo接口方法参数中如果用Set、Map类型,则需要注意用普通的方式初始化;

-------------------------------------------------------------------------------------------------------------------------------------------------

参考:

【解决】hessian 客户端报警告:Hessian/Burlap: xxx is an unknown class in sun.misc.Launcher…… https://blog.csdn.net/fangzhangsc2006/article/details/7975978

警告: Hessian/Burlap: 'com.github.pagehelper.Page' is an unknown class in WebappClassLoader https://blog.csdn.net/qq_38765404/article/details/78108780

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值