百度搜索seo優(yōu)化技巧寧波seo外包推廣排名
問(wèn)題:
周末被迫在家值班,無(wú)聊之際打開(kāi)塵封已久的Bug清單,發(fā)現(xiàn)有Bug拖了幾個(gè)月還沒(méi)解決…
場(chǎng)景是這樣子的,有個(gè)功能是拿Redis緩存熱點(diǎn)數(shù)據(jù)進(jìn)行展示,暫且稱(chēng)它為功能A,有個(gè)另外的功能B,它會(huì)去更新緩存中這個(gè)熱點(diǎn)數(shù)據(jù),另外有定時(shí)任務(wù)去執(zhí)行緩存數(shù)據(jù)持久化
按理說(shuō)這樣子設(shè)計(jì)是沒(méi)得問(wèn)題的。不會(huì)出現(xiàn)數(shù)據(jù)一致性問(wèn)題(信誓旦旦 )
現(xiàn)象:
可是問(wèn)題就出在功能B更新緩存數(shù)據(jù)后,功能A展示的還是舊數(shù)據(jù),且查看Redis緩存數(shù)據(jù)是已經(jīng)更新了的 !
那為啥功能A還能拿到舊的緩存數(shù)據(jù)呢?而且還是有時(shí)會(huì)有時(shí)不會(huì)!擱著給我卡bug是吧!
當(dāng)時(shí)硬是沒(méi)排查出原因,把問(wèn)題定位在了網(wǎng)絡(luò)請(qǐng)求不穩(wěn)定上面,因?yàn)榭刂婆_(tái)報(bào)了 Command timed out after 8 second(s) 這個(gè)問(wèn)題,有時(shí)候請(qǐng)求一直掉隊(duì)!
哎。后面就只是記錄下來(lái)這個(gè)問(wèn)題,沒(méi)再去探究過(guò)了,直至今天有幸,公司給了這個(gè)“值班”機(jī)會(huì),我才又重新去針對(duì)它!
原因
我使用了Java的stream流式操作,但是忘記加終止操作,導(dǎo)致流式操作過(guò)程并沒(méi)有執(zhí)行,所以我功能A從緩存拿數(shù)據(jù)就是不可能的!
那為啥有時(shí)候有可以了呢 ?!?
🐎嘚,我還有個(gè)定時(shí)任務(wù)呢,一分鐘執(zhí)行一次!靠了,當(dāng)時(shí)沒(méi)記起來(lái)這茬,行,馬上給你這流式計(jì)算終止掉!
可惡啊,忘記去collect 終止操作來(lái)將stream映射的結(jié)果進(jìn)行收集了,小樣,拿捏你!
stream在Java中是一種延遲計(jì)算的操作,只有遇到終止操作,才會(huì)觸發(fā)中間操作
解決步驟:
1、終止流式計(jì)算2、排查新問(wèn)題,空指針!
一、終止流式計(jì)算
在代碼塊后面加collect(Collectors.toList())
收集結(jié)果即可
當(dāng)我信誓旦旦去啟動(dòng)項(xiàng)目時(shí),訪問(wèn)報(bào)錯(cuò)空指針…
二、排查新問(wèn)題
空指針還不好解決么?小菜一碟!
我有一個(gè)map,鍵值對(duì)類(lèi)型是Map<String, Integer>
在流式計(jì)算中,我使用get(key)
方式去拿map中的value
因?yàn)槟玫降臄?shù)據(jù)是個(gè)Integer
,我對(duì)象的屬性是long類(lèi)型,所以我給他轉(zhuǎn)了一下。這玩意你跟我說(shuō)會(huì)失敗,開(kāi)玩笑咯。
結(jié)果返回null…
難道真的是我map緩存中沒(méi)有此值嗎?
我在方法執(zhí)行開(kāi)頭 和 流式計(jì)算里面都打印map信息
Map.forEach((key,val) -> log.info("Map:{}","key:"+key+";val:"+val))
結(jié)果你猜怎么著,數(shù)據(jù)一樣,我的天
奇了怪了,咋地會(huì)發(fā)生這種逆天的事情呢?
問(wèn)了一下GPT,他說(shuō)這個(gè)現(xiàn)象很奇怪🤣
后面還是死活找不到問(wèn)題,上了個(gè)廁所回來(lái)后發(fā)現(xiàn)我tm對(duì)象的id屬性是long類(lèi)型的,我拿一個(gè)long類(lèi)型的值去一個(gè)key是String類(lèi)型的map去查,查都出東西就有鬼咯!肯定得先toString一下再去查啊!
Map.get(obj.getId().toString()).longValue();
這樣子才是正確的啊!
起初用的Map.get(obj.getId()).longValue();
瘋了已經(jīng)…