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


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

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

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

@CreateCache(name = "demo", expire = 600)
private Cache<String, ThirdPartyEventResponse> 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());
}

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

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

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

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

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

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

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

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

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

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

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

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM