orika1.5.1版本的map死循環問題

問題現象

在測試環境看到機器cpu報警,且cpu是突然升起來並且一直穩定跑滿在百分之90左右。觀察流量和接口的qps,並沒有突然增加或者有突刺。

問題排查

上機器top -H -p pid + jstack觀察之後發現很多http線程卡在orika的一個weakHashMap的get方法中:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-L1YgzDzP-1590335021764)(https://zlj1217-blog-image.oss-cn-hongkong.aliyuncs.com/mac_picgo/image-20200524232028707.png)]

image-20200524232121915

很明顯,這裏是觸發了經常看到HashMap一類分析文章中的map鏈表成環並且死循環的問題,然後就去查看了orika中的這個類,代碼維護了一個全局的weakHashMap:

// 定義了一個WeakHashMap
	private static volatile WeakHashMap<java.lang.reflect.Type, Integer> knownTypes = new WeakHashMap<java.lang.reflect.Type, Integer>();

這裏有點不明白的是使用的是java1.8,記得代碼中是更改了擴容時候鏈表的遷移方式,避免了成環操作,然後就去看了WeakHashMap的操作,發現原來WeakHashMap並沒有去樹化和改變遷移鏈表的方式,還是可能出現成環,然後在get的時候死循環導致cpu異常。

其實在WeakHashMap的註釋中也看到了對應不同步的說法:

 * <p> Like most collection classes, this class is not synchronized.
 * A synchronized <tt>WeakHashMap</tt> may be constructed using the
 * {@link Collections#synchronizedMap Collections.synchronizedMap}
 * method.

問題解決

這裏嘗試去找了網上的文章和orika的issue,發現有遇到同樣問題的文章和issue:

參考blog

官方issue

這裏都提示了在高版本解決了這個問題。我這裏使用的是orika1.5.1版本的包,升級爲最新的1.5.4之後,再看這個weakHashMap加上了同步方法:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章