最近一直在老家遠程辦公,微信突然響了下,有同事說遇到了一個奇怪的問題,讓我幫忙看下。
現象就是標題所說的緩存獲取不到的問題,我一聽感覺這個問題挺有意思的,決定一探究竟。
下面給出部分代碼還原下案發現場:
<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中已經存在了,證明插入沒問題。
只有使出終極必殺器了,那就是debug源碼。
通過get方法一直往下看,最終到了RedisCache裡面。
然後在這裡打個斷點,看看到底有沒有獲取到Redis中的值,驚訝的發現,值是獲取到了的,如下:
納尼,這是什麼操作。摸了摸我還沒禿頂的後腦勺,我鎖定了下面這行代碼:
<code>CacheValueHolderholder = (CacheValueHolder)this.valueDecoder.apply(bytes); /<code>
猜測應該是解碼的時候出問題了,然後找到了對應的解碼的代碼,用的是kryo框架。
終於在最後一步解碼的時候發現了錯誤,守得雲開見月明啊!
錯誤告訴我們ArrayList缺少構造函數呀,請注意是Arrays裡面的ArrayList。嚇得我趕緊看下代碼,果真是Arrays.asList()構造的參數。
*解決辦法自然就很簡單了,直接用 *java.util.ArrayList即可。
最後想說的是解決問題最重要的是方式和技巧。寫這篇文章的目的也是希望大家在遇到問題的時候不要侷限於表面,可以往深一點去探索。
感興趣的可以關注下我的微信公眾號 猿天地,更多技術文章第一時間閱讀。我的GitHub也有一些開源的代碼 https://github.com/yinjihuan
閱讀更多 猿天地 的文章