25

一次 StackOverflowError 排查,原因竟然和 Dubbo 有关

 5 years ago
source link: https://mp.weixin.qq.com/s/Ga9Wr8oxpg2s-3NTGEt4NQ?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

某天业务方的同事和我反馈,说系统出现了 StackOverflowError .坦白说, Exception 见得过了,但是 Error 倒是很少出现,此时他的心情是这样的

一波猛如虎的操作

我们先来看血淋淋的案发现场

yQRvmyE.jpg!web

从异常栈中很明显发现出现了死循环,其实 StackOverflowError 绝大多数都是死循环、递归引起的.那么,这为什么会出现循环调用呢?我们根据这个溢出的案发现场查看源码

7ZfABvR.jpg!web

如果你是用idea的话,他还会用图标提示你,这里会出现递归调用.

那么问题来了,这里究竟为什么会循环递归调用?由于这个问题,是必然重现的,对于之前查看过我源码解析的老粉丝来说简直是 so easy .我们触发场景,然后把断点打在案发现场,不断把断点放过,反复几次之后,如下图

mEVb2i.jpg!web

经过上面的数据,我们已经粗略看出死循环的迹象.我们把目标锁定在了 currencyavailableCurrencies . 为什么这里会出现反复的循环呢?我们查看一下 Currency 类的源码

1public static Set<Currency> getAvailableCurrencies() {
2
3    //省略...
4}

结合断点的序列化情况可以看出,currency进行json序列化的时候,需要去序列化 availableCurrencies .然后 getAvailableCurrencies() 又包含currency,从而陷入了死循环.

本地重现

为了保证每个粉丝都能参与其中,肥朝抽取了一个必然重现的最简模型.希望肥朝公众号的粉丝都能一起参与进来,而不是每次看完分析过后,还有人一脸懵逼喊着 666 !

U3qyYvz.jpg!web

 1public class FeiChaoDTO {
2
3 private Currency currency;
4
5 public Currency getCurrency() {
6 return currency;
7 }
8
9 public void setCurrency(Currency currency) {
10 this.currency = currency;
11 }
12}
1@Test
2public void test() throws Exception {
3 FeiChaoDTO feiChaoDTO = new FeiChaoDTO();
4 feiChaoDTO.setCurrency(Currency.getInstance("CNY"));
5 String json = JSON.json(feiChaoDTO);
6 System.out.println(json);
7}

如何解决

很明显,出现这个问题的原因是因为该同学用了Dubbo里面的json序列化工具类,因为这个工具并非是Dubbo主流功能,所以关注度不足,自然存在一些不完善的功能,并且在Dubbo 2.6.x 以后版本,已经标注为过期.另外我们再看一下阿里开发手册

yqYR3ej.jpg!web

要解决这个问题方式很简单,既然要json序列化,那么就用主流的json序列化工具,无论是用 fastjsongsonjackson 都有对这些循环的情况做处理,还是那句话,本公众号已经和各大搜索引擎长期合作,按照我的描述搜索,比如 fastjson 循环引用 ,你想要的都有.当然细心的你可能发现,这些主流工具都不会去序列化 availableCurrencies 字段,Dubbo的这个序列化工具处理逻辑和主流的JSON工具处理还是有些不同,当然不用纠结,Dubbo本身定位就是RPC框架,就像肥朝公众号定位就是 源码解析 真实场景源码实战 ,JSON解析我们可以选用上面的三大神器中的一个.

写在最后

近日有粉丝和肥朝反馈在面试过程遇到了如下的问题

v26Zzuf.jpg!web

我只想说,人家不问,你也可以主动嘛.如果你是肥朝的粉丝,在工作、学习上遇到了什么问题,欢迎来撩,主要你主动,我们的故事就开始了!

Ubu2Yvz.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK