小程序本地图片偶尔加载不出来_得亏了它,我才把潜藏那么深的Bug挖出来

9e8f192efdda39b4ac4b2515cc60b46d.gif

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

事故背景

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

ad101155474fc4bb80807241d61413fe.png

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

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

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

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

arthas 大显身手

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

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

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

3fd9c09878aa4b461f0eaf342446ee1e.png

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

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

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

e3521725300241319caffcebc9464978.png

居然报错了,错误还跟我们之前在 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。

464f2f157889ca2c55df059bde54bd2b.png

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

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

即将揭开真相

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

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

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

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

e33232f0388e5fdc0573e1aa363c6248.png

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

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

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

总结

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

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

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

技术交流可以扫下面图片加我微信。

欢迎关注个站

96636d07e22b7fbaaae7a14b78f3055f.png

往期回顾

微服务自动化部署CI/CD

如何利用k8s拉取私有仓库镜像

个站建设基础教程

ArrayList、LinkedList 你真的了解吗?

大佬整理的mysql规范,分享给大家

如果张东升是个程序员

微服务架构设计之解耦合

浅谈负载均衡

Oauth2的认证实战-HA篇

Oauth2的授权码模式《上》

浅谈开发与研发之差异

浅谈 Java 集合 | 底层源码解析

基于 Sentinel 作熔断 | 文末赠资料

基础设施服务k8s快速部署之HA篇

今天被问微服务,这几点,让面试官刮目相看

Spring cloud 之多种方式限流(实战)

Spring cloud 之熔断机制(实战)

面试被问finally 和 return,到底谁先执行?

Springcloud Oauth2 HA篇

Spring Cloud Kubernetes之实战一配置管理

Spring Cloud Kubernetes之实战二服务注册与发现

Spring Cloud Kubernetes之实战三网关Gateway

cb169ceac5963d6de037bd52a05b09ce.png

cf956ec57b83e851e5b30d0451f46322.png

bffb487417f1db2dd5f53d3d81d9762d.png

关注公众号,回复入群,获取更多惊喜!公众号(天山六路折梅手)里回复 ES、Flink、Java、Kafka、MQ、ML、监控、大数据、k8s 等关键字可以查看更多关键字对应的文章。

79789beb68adf06cdaab392cd8166eab.gif

762e427a012aab6ca7d1afd1632cb623.gif

点击 "damon8.cn" 获取更好的阅读体验!

❤️给个「在看」,是对我最大的支持❤️
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
八卦的卦象有八种,分别是乾、坤、震、巽、坎、离、艮、兑。 1. 乾卦:乾卦为天,象征着刚健、创始、领导、创新、父亲、掌权等。乾卦为阳卦,其形象为九个实心点排成的正方形。 2. 坤卦:坤卦为地,象征着柔顺、包容、母亲、承、教育、保护等。坤卦为阴卦,其形象为九个空心点排成的正方形。 3. 震卦:震卦为雷,象征着动、刺激、震撼、启发、领导、进取等。震卦为阳卦,其形象为上三个实心点,下三个空心点,中间一个实心点的图案。 4. 巽卦:巽卦为风,象征着温和、适应、谦虚、柔顺、领导、协调等。巽卦为阴卦,其形象为上三个空心点,下三个实心点,中间一个空心点的图案。 5. 坎卦:坎卦为水,象征着险恶、寒冷、沉静、洞察、领导、进取等。坎卦为阳卦,其形象为上三个空心点,下三个实心点,中间一个空心点的图案。 6. 离卦:离卦为火,象征着热情、阳刚、明亮、照耀、领导、创新等。离卦为阴卦,其形象为上三个实心点,下三个空心点,中间一个实心点的图案。 7. 艮卦:艮卦为山,象征着静止、守护、思考、固守、领导、稳重等。艮卦为阳卦,其形象为上三个实心点,下三个空心点,中间一个实心点的图案。 8. 兑卦:兑卦为泽,象征着潜藏、润泽、柔和、互相滋养、领导、合作等。兑卦为阴卦,其形象为上三个空心点,下三个实心点,中间一个空心点的图案。 以上就是八个卦象的详细解释,每个卦象都有其独特的特点和象征含义,可以用来预测、卜筮、指导人生等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值