关于这周工作中遇到的关于缓存问题的记录
序:本周在工作中遇到了一些麻煩,解決過(guò)程比較曲折和辛苦,特此記錄,留作經(jīng)驗(yàn)供以后參考
?
發(fā)現(xiàn)問(wèn)題:周一上班的時(shí)候,運(yùn)營(yíng)打電話(huà)來(lái)說(shuō),我們上個(gè)月做的一個(gè)活動(dòng)感覺(jué)數(shù)據(jù)不對(duì),商家過(guò)來(lái)投訴了。結(jié)果我數(shù)據(jù)庫(kù)一查,數(shù)據(jù)還真有問(wèn)題!這次的活動(dòng)采用的是頁(yè)面上使用緩存系統(tǒng)顯示活動(dòng)數(shù)值(總金額),同時(shí)在后臺(tái)記錄詳細(xì)的每條活動(dòng)數(shù)據(jù)的辦法。每次用戶(hù)發(fā)生業(yè)務(wù)行為的時(shí)候都會(huì)在后臺(tái)的緩存的總金額上增加,同時(shí)記錄這次行為發(fā)生的金額數(shù)。結(jié)果我周一把數(shù)據(jù)庫(kù)的記錄加一起來(lái)一算,發(fā)現(xiàn)和頁(yè)面上緩存的總金額竟然差了將近一半!
?
解決的過(guò)程:
1.由于數(shù)據(jù)庫(kù)記錄了每次業(yè)務(wù)行為的具體數(shù)據(jù),而且比緩存的總金額要多。我第一時(shí)間想到的就是緩存系統(tǒng)哪里出錯(cuò)了。于是我先去服務(wù)器上找日志,可惜的是活動(dòng)時(shí)間過(guò)去太久,服務(wù)器上的日志已經(jīng)沒(méi)有當(dāng)時(shí)的記錄了(郁悶!)。于是我只能靠自己來(lái)找出當(dāng)時(shí)的BUG了。
2.我想到在上線(xiàn)之前我已經(jīng)在線(xiàn)下環(huán)境和預(yù)發(fā)環(huán)境做過(guò)測(cè)試,緩存的數(shù)據(jù)和數(shù)據(jù)庫(kù)的數(shù)據(jù)是會(huì)保持一致的。難道是因?yàn)榫€(xiàn)上的環(huán)境有2臺(tái)服務(wù)器,又或者是在高并發(fā)大數(shù)據(jù)的情況下,才會(huì)產(chǎn)生的錯(cuò)誤,又或者是其中某一臺(tái)服務(wù)器的緩存服務(wù)器發(fā)生故障了?(因?yàn)閿?shù)值剛好差了近一半么,如果其中一臺(tái)服務(wù)器的緩存出錯(cuò)了,數(shù)值就符合了)。于是我修改了代碼,重現(xiàn)了當(dāng)時(shí)的業(yè)務(wù)場(chǎng)景,結(jié)果發(fā)現(xiàn)在比較高的并發(fā)量的情況下,2臺(tái)服務(wù)器均未出現(xiàn)緩存服務(wù)故障和數(shù)據(jù)庫(kù)不一致的現(xiàn)象。之后我又詢(xún)問(wèn)了其它開(kāi)發(fā)和緩存部門(mén)的人,確定了在當(dāng)時(shí)的訪(fǎng)問(wèn)量下,緩存和服務(wù)器應(yīng)該不會(huì)出現(xiàn)瓶頸。于是乎,我的假設(shè)失敗了,BUG還是沒(méi)找到。
3.在接下來(lái)的一天里,我詳細(xì)檢查了各個(gè)地方,進(jìn)行了各種假設(shè),均為能測(cè)出這個(gè)數(shù)據(jù)不一致的BUG。而且要命的是,我在服務(wù)器上模擬當(dāng)時(shí)的場(chǎng)景也沒(méi)有出現(xiàn)這個(gè)BUG。于是我想到,這個(gè)BUG可能是那種只有在特定時(shí)間或著條件下才會(huì)出現(xiàn)的狀況。一般像這種情況的問(wèn)題最難處置了,因?yàn)榭赡艹鰡?wèn)題的地方可能已經(jīng)消失了,不知道什么時(shí)候又會(huì)出現(xiàn)。第二天,我正向運(yùn)營(yíng)主管反應(yīng)這個(gè)情況打算放棄的時(shí)候,他告訴了我一個(gè)重要的線(xiàn)索!他說(shuō)在活動(dòng)結(jié)束前的時(shí)候,他發(fā)現(xiàn)活動(dòng)的總金額有過(guò)突然減少的情況,這個(gè)情況是出乎我意料的。因?yàn)橹暗囊恢币詾槭蔷彺嫦到y(tǒng)哪里出問(wèn)題,導(dǎo)致增加的計(jì)數(shù)器沒(méi)起效果。但是他說(shuō)總金額有突然變少過(guò),我寫(xiě)的業(yè)務(wù)代碼中根本沒(méi)有減少金額的邏輯,也就不可能存在金額減少的情況。于是乎,我把偵查重點(diǎn)又轉(zhuǎn)移到了緩存系統(tǒng)本身上去。因?yàn)榧热晃覍?xiě)的代碼根本不可能導(dǎo)致總金額的減少,那就一定是緩存系統(tǒng)本身出了什么問(wèn)題,才會(huì)出現(xiàn)這種金額減少的狀況。
4.接來(lái)下,我與緩存系統(tǒng)的技術(shù)支持電話(huà)里確認(rèn)。詢(xún)問(wèn)了到底什么情況下,緩存系統(tǒng)會(huì)有金額減少的狀況發(fā)生。在給他展示了我的關(guān)鍵性代碼之后,他告訴我,如果我存在緩存里的數(shù)值“丟失”的話(huà),因?yàn)槲以诖a里沒(méi)有做“防災(zāi)”處理,數(shù)值可能是會(huì)重新歸零的。緩存數(shù)值的“丟失”!這是我在之前沒(méi)有考慮過(guò)的情況,因?yàn)槲抑霸?xún)問(wèn)過(guò)開(kāi)發(fā)的前輩,他們說(shuō)這套緩存系統(tǒng)十分的穩(wěn)定,因此我就大膽的直接使用它進(jìn)行了業(yè)務(wù)數(shù)值的展現(xiàn)。而且從緩存系統(tǒng)的監(jiān)控里,我也找不到類(lèi)似于緩存溢出的情況。后來(lái)這個(gè)緩存部門(mén)的技術(shù)支持告訴我,由于我使用的是一塊公用的緩存服務(wù)器,即使我本身分配的緩存空間還很多,但是如果其它用戶(hù)此時(shí)有很大的緩存進(jìn)來(lái)的話(huà),是有可能把我駐留在內(nèi)存里的數(shù)值給“丟失”的。
5.到這里,我基本上就想通了。在我上個(gè)月活動(dòng)的那幾天里,由于緩存系統(tǒng)其它用戶(hù)出現(xiàn)的某些大負(fù)載量的狀況,把我保留在緩存系統(tǒng)里的業(yè)務(wù)數(shù)據(jù)(總金額)給弄“丟失”了。而我由于天真和大意,沒(méi)有考慮到緩存系統(tǒng)數(shù)值丟失的狀況,只是一味的往上加一,即使在緩存系統(tǒng)里的數(shù)值“丟失”歸零之后。于是就出現(xiàn)了數(shù)值突然下降,最終和實(shí)際數(shù)值不一致的情況。找到了問(wèn)題的原因,解決辦法也很容易想到。就是在這個(gè)業(yè)務(wù)場(chǎng)景下,考慮到緩存可能“丟失”的情況,在每次給緩存加一的時(shí)候,先判斷下緩存是否存在,如果不存在就去數(shù)據(jù)庫(kù)里取當(dāng)前記錄的總值。
?
經(jīng)驗(yàn)總結(jié):
找BUG往往是程序員最痛苦的事情之一,而像我這次碰到的這種在某些情況下才會(huì)發(fā)生的BUG,就更是難以被發(fā)現(xiàn)和處理。這時(shí)往往就得像偵探辦案似的,收集各種線(xiàn)索,進(jìn)行各種假設(shè)。模擬業(yè)務(wù)場(chǎng)景,往往是程序員找出BUG,最常使用的手段,但當(dāng)這次這種無(wú)法重現(xiàn)的場(chǎng)景出現(xiàn)的時(shí)候,就只能靠“線(xiàn)索”了。“線(xiàn)索”是指那些有用的信息,比如運(yùn)營(yíng)人員反映的數(shù)值突然下降過(guò)的事,比如日志和數(shù)據(jù)記錄。這些平時(shí)看起來(lái)不重要的事物,在這時(shí)都有可能會(huì)變成有用的“線(xiàn)索”。所以平時(shí)保存日志和備份數(shù)據(jù),還有監(jiān)控記錄,這些東西在分布式,大數(shù)據(jù)的系統(tǒng)下就變得很重要了。
另外,還有最重要的一點(diǎn),就是對(duì)找“BUG'這件事本身的毅力也很重要,因?yàn)樵谡摇盉UG'的過(guò)程中,可能會(huì)四處碰壁,這時(shí)如果放棄了,那這個(gè)BUG就永遠(yuǎn)淹沒(méi)成為過(guò)去了。但是如果你堅(jiān)持下去,把他找出來(lái),那你就能優(yōu)化自己的代碼和系統(tǒng),對(duì)于自身也是技術(shù)的增長(zhǎng)和經(jīng)驗(yàn)的積累。
轉(zhuǎn)載于:https://www.cnblogs.com/xujanus/p/3849342.html
總結(jié)
以上是生活随笔為你收集整理的关于这周工作中遇到的关于缓存问题的记录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: UITextField
- 下一篇: 对集合数据进行排序