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的更多相关文章

  1. Dubbo学习笔记10:Dubbo服务消费方启动流程源码分析

    同理我们看下服务消费端启动流程时序图: 在<Dubbo整体架构分析>一文中,我们提到服务消费方需要使用ReferenceConfig API来消费服务,具体是调用代码(1)get()方法来 ...

  2. Spring Cloud Alibaba(四)实现Dubbo服务消费

    本项目演示如何使用 Spring Cloud Alibaba 完成 Dubbo 的RPC调用. Spring Cloud与Dubbo Spring Cloud是一套完整的微服务架构方案 Dubbo是国 ...

  3. 【docker】docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志

    如题: docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志 场景再现: docker部署并启动 ...

  4. 源码分析Dubbo服务消费端启动流程

    通过前面文章详解,我们知道Dubbo服务消费者标签dubbo:reference最终会在Spring容器中创建一个对应的ReferenceBean实例,而ReferenceBean实现了Spring生 ...

  5. (万字好文)Dubbo服务熔断与降级的深入讲解&代码实战

    原文链接:(万字好文)Dubbo服务熔断与降级的深入讲解&代码实战 一.Dubbo服务降级实战 1 mock 机制 谈到服务降级,Dubbo 本身就提供了服务降级的机制:而 Dubbo 的服务 ...

  6. Dubbo服务集群、服务启动依赖检查

    一.什么叫Dubbo服务集群 指把同一个服务部署到多台机器,然后通过Dubbo服务集群的容错配置实现一台机器的服务挂掉之后自动切换到另外的一台机器 二.Dubbo服务集群容错配置--集群容错模式 标签 ...

  7. dubbo服务暴露

    想熟悉dubbo源码,首先要知道dubbo extensionLoader,而dubbo的这种扩展机制,是根据java spi衍生而来. 这是基础,但是我放在后面说明. 一:dubbo demo pr ...

  8. dubbo系列四、dubbo服务暴露过程源码解析

    一.代码准备 1.示例代码 参考dubbo系列二.dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台) 2.简单了解下spring自定义标签 https://w ...

  9. 关于dubbo的provider和consumer都配置timeout超时时间的情况

    本文转自:http://blog.csdn.net/lkforce/article/details/54380201 前言 在dubbo的provider和consumer的配置文件中,如果都配置了t ...

随机推荐

  1. JavaSpring【六、AOP的API】

    AOP API Spring1.2历史用法,现在仍然支持 现在xml配置和注解的用法是基于API的,只是比较简便

  2. 嵌入式Linux应用开发完全手册读书笔记——常用的命令

    嵌入式开发中常用的命令 grep命令 用法:grep [option] PATTERN [FILE...] 例如: 在内核目录下查找包含"request_irq"字样的文件 gre ...

  3. 【Java基础 项目实例 -- Bank项目2】Account 和 customer 对象

    总结: customer.setAccount(account); //引用,日后的account 和 customer.getAccount()的结果始终一致 实验目的 扩展银行项目,添加一个 Cu ...

  4. ThreadPoolExecutor源码分析二

      接上文,这里继续分析源码 private static final int COUNT_BITS = Integer.SIZE - 3; private static final int CAPA ...

  5. 洛谷P2664 树上游戏——点分治

    原题链接 被点分治虐的心态爆炸了 题解 发现直接统计路径上的颜色数量很难,考虑转化一下统计方式.对于某一种颜色\(c\),它对一个点的贡献为从这个点出发且包含这种颜色的路径条数. 于是我们先点分一下, ...

  6. freertos,串口接收数据后如何发送给任务

    http://www.stmcu.org.cn/module/forum/thread-610230-1-1.html http://www.stmcu.org.cn/module/forum/thr ...

  7. struts2提交表单注意事项 (3)

    供应商模块 需求:实现供应商的列表.添加.修改.删除三个功能 注意:修改时,不允许修改供应商编号 添加时,不允许显现的添加供应商编号 删除时,进行逻辑删除(根据主键将该条数据不再显示在列表) 物理删除 ...

  8. Codeforces Round #586 (Div. 1 + Div. 2) B. Multiplication Table

    链接: https://codeforces.com/contest/1220/problem/B 题意: Sasha grew up and went to first grade. To cele ...

  9. 设置springboot、mysql、nginx,tomcat文件大小(大集合)

    1.springboot设置文件大小 第一种: application.properties中添加 spring.http.multipart.maxFileSize=10MBspring.http. ...

  10. Sysinternals

    http://baike.baidu.com/link?url=LwEFVIcB4h8WaS6sVVH2toBJ0GZUA28yymm1sLsGpDrzF3G2BCZenlHwIsYZdVJZQExE ...