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<枚举类C, Object> 方法名(Long xxId, Set<枚举类C> xxSet);
检查XxxBolt中调接口的代码,
调用如下:
Long xxId = ...;
Set<类B, Object> xxSet = new HashSet{{
add(枚举C.枚举1,xxx);
add(枚举C.枚举2,xxx);
...
}}
Map<枚举类C, Object> result = 方法名(Long xxId, Set<枚举类C> 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<枚举B>
{
}
类名是1,这样XxxBolt$1名称解释得通,但它是哪里产生的呢?
刚才枚举B已确定是最新的,于是我们把目光锁定在了这个HashSet的构造上
Set<类B, Object> 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<类B, Object> xxSet = new HashSet<类B, Object>();
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
dubbo服务provider方打印警告日志,getDeserializer - Hessian/Burla 'xxx' is an unknown class的更多相关文章
- Dubbo学习笔记10:Dubbo服务消费方启动流程源码分析
同理我们看下服务消费端启动流程时序图: 在<Dubbo整体架构分析>一文中,我们提到服务消费方需要使用ReferenceConfig API来消费服务,具体是调用代码(1)get()方法来 ...
- Spring Cloud Alibaba(四)实现Dubbo服务消费
本项目演示如何使用 Spring Cloud Alibaba 完成 Dubbo 的RPC调用. Spring Cloud与Dubbo Spring Cloud是一套完整的微服务架构方案 Dubbo是国 ...
- 【docker】docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志
如题: docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志 场景再现: docker部署并启动 ...
- 源码分析Dubbo服务消费端启动流程
通过前面文章详解,我们知道Dubbo服务消费者标签dubbo:reference最终会在Spring容器中创建一个对应的ReferenceBean实例,而ReferenceBean实现了Spring生 ...
- (万字好文)Dubbo服务熔断与降级的深入讲解&代码实战
原文链接:(万字好文)Dubbo服务熔断与降级的深入讲解&代码实战 一.Dubbo服务降级实战 1 mock 机制 谈到服务降级,Dubbo 本身就提供了服务降级的机制:而 Dubbo 的服务 ...
- Dubbo服务集群、服务启动依赖检查
一.什么叫Dubbo服务集群 指把同一个服务部署到多台机器,然后通过Dubbo服务集群的容错配置实现一台机器的服务挂掉之后自动切换到另外的一台机器 二.Dubbo服务集群容错配置--集群容错模式 标签 ...
- dubbo服务暴露
想熟悉dubbo源码,首先要知道dubbo extensionLoader,而dubbo的这种扩展机制,是根据java spi衍生而来. 这是基础,但是我放在后面说明. 一:dubbo demo pr ...
- dubbo系列四、dubbo服务暴露过程源码解析
一.代码准备 1.示例代码 参考dubbo系列二.dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台) 2.简单了解下spring自定义标签 https://w ...
- 关于dubbo的provider和consumer都配置timeout超时时间的情况
本文转自:http://blog.csdn.net/lkforce/article/details/54380201 前言 在dubbo的provider和consumer的配置文件中,如果都配置了t ...
随机推荐
- .NET 使用事物调用存储过程
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...
- java之JVM学习--简单理解编译和运行的过程之概览
java代码编译流程图: java字节码执行由JVM执行引擎完成 Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码编译机制 类加载机制 类执行机制 Java源码编译机制 Jav ...
- DX使用随记--其他
1. 百分号显示格式 百分号:{0:P}表示显示为百分号模式.如数据源中为0.5.表示出来为50%
- linux驱动程序与菜单关联
- Flutter——Column组件(垂直布局组件)
Column组件的常用属性 属性 说明 mainAxisAlignment 主轴的排序方式 crossAxisAlignment 次轴的排序方式 children 组件子元素 import 'pack ...
- GenericJDBCException: could not execute statement 错误解决
"message":"could not execute statement; nested exception is org.hibernate.exception.G ...
- [AHOI2007]密码箱 (数学 + 暴力)
链接:https://ac.nowcoder.com/acm/problem/19877来源:牛客网 题目描述 在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能 ...
- (四)关于java.lang.IllegalMonitorStateException异常说明
1.异常原因及解释 首先你要了解这个异常为什么会抛出,这个异常会在三种情况下抛出:1>当前线程不含有当前对象的锁资源的时候,调用obj.wait()方法;2>当前线程不含有当前对象的锁资源 ...
- vue 后退不刷新,前进刷新 keep-alive
最近在开发中遇到了这样的一个问题: A.B.C三个页面,有如下这样的场景: (1)从页面A离开进入B或C的时候,缓存A页面的数据,并且返回到A后,能保持A页面的跳转前职位 (2)离开B进入C的时候,缓 ...
- springboot 详解RestControllerAdvice(ControllerAdvice)(转)
springboot 详解RestControllerAdvice(ControllerAdvice)拦截异常并统一处理简介 @Target({ElementType.TYPE}) @Retentio ...