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

肥朝發表於2019-03-20

前言

某天業務方的同事和我反饋,說系統出現了StackOverflowError.坦白說,Exception見得過了,但是Error倒是很少出現,此時他的心情是這樣的

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

一波猛如虎的操作

我們先來看血淋淋的案發現場

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

從異常棧中很明顯發現出現了死迴圈,其實StackOverflowError絕大多數都是死迴圈、遞迴引起的.那麼,這為什麼會出現迴圈呼叫呢?我們根據這個溢位的案發現場檢視原始碼

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

如果你是用idea的話,他還會用圖示提示你,這裡會出現遞迴呼叫.

那麼問題來了,這裡究竟為什麼會迴圈遞迴呼叫?由於這個問題,是必然重現的,對於之前檢視過我原始碼解析的老粉絲來說簡直是so easy.我們觸發場景,然後把斷點打在案發現場,不斷把斷點放過,反覆幾次之後,如下圖

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

經過上面的資料,我們已經粗略看出死迴圈的跡象.我們把目標鎖定在了currencyavailableCurrencies. 為什麼這裡會出現反覆的迴圈呢?我們檢視一下Currency類的原始碼

public static Set<Currency> getAvailableCurrencies() {

	//省略...
}
複製程式碼

結合斷點的序列化情況可以看出,currency進行json序列化的時候,需要去序列化availableCurrencies.然後getAvailableCurrencies()又包含currency,從而陷入了死迴圈.

本地重現

為了保證每個粉絲都能參與其中,肥朝抽取了一個必然重現的最簡模型.希望肥朝公眾號的粉絲都能一起參與進來,而不是每次看完分析過後,還有人一臉懵逼喊著666!

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

public class FeiChaoDTO {

	private Currency currency;

	public Currency getCurrency() {
		return currency;
	}

	public void setCurrency(Currency currency) {
		this.currency = currency;
	}
}
複製程式碼
@Test
public void test() throws Exception {
	FeiChaoDTO feiChaoDTO = new FeiChaoDTO();
	feiChaoDTO.setCurrency(Currency.getInstance("CNY"));
	String json = JSON.json(feiChaoDTO);
	System.out.println(json);
}
複製程式碼

如何解決

很明顯,出現這個問題的原因是因為該同學用了Dubbo裡面的json序列化工具類,因為這個工具並非是Dubbo主流功能,所以關注度不足,自然存在一些不完善的功能,並且在Dubbo2.6.x以後版本,已經標註為過期.另外我們再看一下阿里開發手冊

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

要解決這個問題方式很簡單,既然要json序列化,那麼就用主流的json序列化工具,無論是用fastjsongsonjackson都有對這些迴圈的情況做處理,還是那句話,本公眾號已經和各大搜尋引擎長期合作,按照我的描述搜尋,比如fastjson 迴圈引用,你想要的都有.當然細心的你可能發現,這些主流工具都不會去序列化availableCurrencies欄位,Dubbo的這個序列化工具處理邏輯和主流的JSON工具處理還是有些不同,當然不用糾結,Dubbo本身定位就是RPC框架,就像肥朝公眾號定位就是原始碼解析真實場景原始碼實戰,JSON解析我們可以選用上面的三大神器中的一個.

寫在最後

近日有粉絲和肥朝反饋在面試過程遇到了如下的問題

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

我只想說,人家不問你也可以主動嘛.如果你是肥朝的粉絲,在工作、學習上遇到了什麼問題,歡迎來撩,只要你主動,我們的故事就開始了!

肥朝 是一個專注於 原理、原始碼、開發技巧的技術公眾號,號內原創專題式原始碼解析、真實場景原始碼原理實戰(重點)。掃描下面二維碼關注肥朝,讓本該造火箭的你,不再擰螺絲!

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

相關文章