02.26 驚訝!緩存剛Put再Get居然獲取不到?

最近一直在老家遠程辦公,微信突然響了下,有同事說遇到了一個奇怪的問題,讓我幫忙看下。

現象就是標題所說的緩存獲取不到的問題,我一聽感覺這個問題挺有意思的,決定一探究竟。

下面給出部分代碼還原下案發現場:

<code>@CreateCache(name = "demo", expire = 600)
private Cache<string> cache;
@Test
public void test() {
ThirdPartyEventResponse eventResponse = new ThirdPartyEventResponse();
eventResponse.setTicketCategories(Arrays.asList(ticketCategoryResponse));
// 省略 .....
// 添加
cache.put(DisChannelType.PIAONIU.getValue(), eventResponse);
// 獲取
ThirdPartyEventResponse resp = cache.get(DisChannelType.PIAONIU.getValue());
}
/<string>/<code>

Put之後馬上Get,居然獲取不到值。這就有點匪夷所思了,我們來好好排查下。

首先過期時間為600秒,肯定不是剛保存就過期了的原因。

然後去Redis中查看到底有沒有Put進去,發現數據在Redis中已經存在了,證明插入沒問題。

驚訝!緩存剛Put再Get居然獲取不到?


只有使出終極必殺器了,那就是debug源碼。

通過get方法一直往下看,最終到了RedisCache裡面。

驚訝!緩存剛Put再Get居然獲取不到?


然後在這裡打個斷點,看看到底有沒有獲取到Redis中的值,驚訝的發現,值是獲取到了的,如下:

驚訝!緩存剛Put再Get居然獲取不到?


納尼,這是什麼操作。摸了摸我還沒禿頂的後腦勺,我鎖定了下面這行代碼:

<code>CacheValueHolder 
holder = (CacheValueHolder)this.valueDecoder.apply(bytes);
/<code>

猜測應該是解碼的時候出問題了,然後找到了對應的解碼的代碼,用的是kryo框架。

驚訝!緩存剛Put再Get居然獲取不到?


終於在最後一步解碼的時候發現了錯誤,守得雲開見月明啊!

驚訝!緩存剛Put再Get居然獲取不到?


錯誤告訴我們ArrayList缺少構造函數呀,請注意是Arrays裡面的ArrayList。嚇得我趕緊看下代碼,果真是Arrays.asList()構造的參數。

驚訝!緩存剛Put再Get居然獲取不到?


*解決辦法自然就很簡單了,直接用 *java.util.ArrayList即可。

最後想說的是解決問題最重要的是方式和技巧。寫這篇文章的目的也是希望大家在遇到問題的時候不要侷限於表面,可以往深一點去探索。


感興趣的可以關注下我的微信公眾號 猿天地,更多技術文章第一時間閱讀。我的GitHub也有一些開源的代碼 https://github.com/yinjihuan


分享到:


相關文章: