2020年写了很多事故解决的文章,并不是我绞尽脑汁想出来的,而是真的遇到了这些问题。通过文章的方式记录下来,分享出去,才有意义。

事故背景

首先看下面的图吧,这是我从cat上截的图。

可以看到是一个Rpc调用的错误,从错误中我们只能分析出这个Rpc的请求成功了,并且返回了,因为都走到了反序列化这步。

最后是在创建DTO对象的时候报错了,Could not initalize class xxxxx.DTO说明了这一点。

作为一个调用方,虽然看到了明确的错误,但还是要本着严谨的态度去排查问题,还是先确认服务提供者到底有没有问题,跟同事确认了,服务提供方没问题,通过telnet可以正常invoke。

好了,到这为止就把背景交代清楚了,能不能将这个潜藏的Bug找出来就各显身手吧。

arthas大显身手

要想效率高,那必须得有好用的工具呀!arthas挺身而出,都毛遂自荐了,不用白不用。

首先使用sc命令查看JVM已加载的类信息,就看这个不能实列化的类到底有没有被成功加载。

sc -d 类全路径 (打印类的详细信息)

类的信息都被打印出来了,足以证明这个类被加载了。

然后打印下类里面的字段,看看有没有丢失什么的

sc -d -f 类全路径 (打印出类的Field信息)

居然报错了,错误还跟我们之前在cat中看到的一模一样,这边也是要是创建对象,然后反射获取所有字段信息,由于不能创建对象,直接报错了。

就这么结束了吗?怎么可能,还没下班呢,接着走下去。。。。

现在我开始怀疑这个class是不是有问题,然后就开始用arthas的另一个命令jad来反编译。

通过jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于我们理解业务逻辑,也能让我们知道代码跟本地的到底是不是一致。

jad --source-only 类全路径

执行完后,什么也没输出,我一度怀疑这个命令是不是我用错了,然后我试了下jad --source-only java.lang.String 发现命令没问题,就是那个class有问题。

这时我想起还有一个redefine命令可以用于加载外部的.class文件,看看能不能加载进来。于是我将lib目录里面依赖的jar包解压了,然后用redefine去加载那个不能反编译的class。

居然告诉我是一个无效的class,尝试多次都无法让这个class现出庐山真面目。

最后没办法,只能将这个class弄到本地,拖入IDEA中反编译,对比了下代码,跟git仓库里面的一模一样,也就不存在jar包损坏的问题。

即将揭开真相

到目前为止,有效的线索如下:

  • class已加载,但是无法实例化
  • 通过本地反编译,代码是完整的

越在这种没有思路的情况下越要静下心来思考,于是再次看了一遍源码,发现这个类中有引用一个外部的自定义异常类。

然后我用sc -d去查看这个类的信息,告诉我不存在,终于明白了。

看上面这张图,项目A依赖了API,API中依赖了Common,Common中又依赖了很多其他的三方Jar包。

由于项目A和Common中依赖的三方Jar包冲突了,所以项目A中之前就简单粗暴的把Common给排除了,冲突是解决了。

在进行RPC调用的时候,请求的数据响应回来后需要反序列化成对象,这个时候去创建对象失败了,因为类中依赖了某个外部的类,但在当前项目中没有加载进来,所以就报错了。

总结

这次的问题归根到底还是没有想到一个API会依赖其他的模块,本身API作为RPC调用客户端就应该简洁。

其实在做exclusion的时候应该只exclusion有冲突的三方Jar,不应该将整个Common都exclusion掉。

最后就是合理的利用方便快速的工具帮助我们快速的排查问题,arthas就是这个好帮手,通过arthas我们可以进一步排除程序启动后加载的class有没有问题,进一步缩小范围。

得亏了它,我才把潜藏那么深的Bug挖出来的更多相关文章

  1. 《Entity Framework 6 Recipes》中文翻译系列 (26) ------ 第五章 加载实体和导航属性之延缓加载关联实体和在别的LINQ查询操作中使用Include()方法

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-7  在别的LINQ查询操作中使用Include()方法 问题 你有一个LINQ ...

  2. 关于e820cycles参数

    关于e820cycles参数http://bbs.wuyou.net/forum.php?mod=redirect&goto=findpost&ptid=327458&pid= ...

  3. 3500常用汉字与标点符号(已排除不支持GB2312的)

    .?!,.::“”‘’…()<>〈〉[].,:;!?-'_"'()[]<>|&~;+-*/=<>0123456789ABCEFGHIJKLMNOP ...

  4. 2015移动安全挑战赛(阿里&看雪主办)第一题分析

    今天在网上看到了阿里移动安全比赛的第一次,并且说难度不大,便拿来看了看. 主体就是找出一个密码输进去,然后看正误. 这个题是纯Java层的一个题,也没用进行什么保护.可以直接反编译. 登陆Button ...

  5. [商业_法务] 2、注册公司起名很费劲,用C++怒写个随机名字生成器

    前言 博主最近在注册公司,由于之前听说过注册公司的名字很难通过,于是便直接找代理去帮忙跑趟,为确保万无一失,还自己绞尽脑汁想了几个很奇葩的名字(噬菌体.云木.灌木.杏仁...). 但是不幸的是那些奇葩 ...

  6. 走进Spark生态圈:环境的安装与配置

    什么是Spark? Apache Spark 是一种大规模数据处理的快速通用引擎,使用基于内存的处理方式,较与MapReduce而言,解决了其shuffle多次IO操作带来的效率低问题,从而达到快速的 ...

  7. Python抓取百度汉字笔画的gif

    偶然发现百度汉语里面,有一笔一划的汉字顺序:          觉得这个动态的图片,等以后娃长大了,可以用这个教写字.然后就去找找常用汉字,现代汉语常用字表 .拿到这里面的汉字,做两个数组出来,一共是 ...

  8. MT4用EA测试历史数据时日志出现:stopped because of stop out

    今天用嘉盛的MT4测试一个EA,谁知道才走了十几天数据就完 了,看结果本金也没亏完啊,才亏了一半,而且我测的是1年的时间. 查看日志一有条警告:stopped because of stop out, ...

  9. information_schema系列十

    information_schema系列十   1:INNODB_FT_CONFIG 这张表存的是全文索引的信息,查询前可以先通过以下语句查询一下开启全文索引的表: show variables li ...

随机推荐

  1. 爬虫笔记(十一)——认识cookie

    什么是cookie? 在爬虫的使用中,如果涉及登录等操作时,经常会使用到cookie.简单的来说,我们访问每一个互联网页面,都是通过HTTP协议进行的,而HTTP协议是一个无状态协议,所谓的无状态协议 ...

  2. platform 平台驱动——设备的写作流程

    说明:在内核源码里会有很多已经实现的驱动,对于我们来说只需要写好设备文件即可,但是我们如何知道驱动需要那些数据,以及有哪些驱动呢? 解决: 1.首先在内核源码目录下执行执行菜单配置命令: make m ...

  3. MySQL数据库中索引的数据结构是什么?(B树和B+树的区别)

    B树(又叫平衡多路查找树) 注意B-树就是B树,-只是一个符号. B树的性质(一颗M阶B树的特性如下) 1.定义任意非叶子结点最多只有M个儿子,且M>2: 2.根结点的儿子数为[2, M]: 3 ...

  4. EternalBlue永恒之蓝漏洞复现

    EternalBlue漏洞复现 1.    实训目的 永恒之蓝(EternalBlue)是由美国国家安全局开发的漏洞利用程序,对应微软漏洞编号ms17-010.该漏洞利用工具由一个名为”影子经济人”( ...

  5. 十三、linux-mysql的mysql的核心优化思想

    一.数据库运维管理思想核心 1.未雨绸缪,不要停留在制度上,而是要实际做出来 2.亡羊补牢,举一反三,不要好了伤疤忘了疼 3.完善的框架设计及备份.恢复策略 4.定期思考,并实战模拟以上策略演练 二. ...

  6. 四剑客(awk)

    AWK AWK简介 虽然sed编辑器是非常方便自动修改文本文件的工具,但其也有自身的限制.通常你需要一个用来处理文件中的数据的更高级工具,它能提供一个类编程环境来修改和重新组织文件中的数据.这正是ga ...

  7. [LC] 114. Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1 ...

  8. MOOC(9)- 登录接口返回的cookie中有多个token

  9. windows server 2008 r2配置NTP时间服务器

    windows server 2008做NTP服务器与H3C网络设备组网首先WINDOWS SERVER 2008默认是关闭NTP服务的,需要通过修改注册表开启方法如下:--------------- ...

  10. LeetCode Day 8

    LeetCode0015 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 例如, 给 ...