解決甩鍋的一大難題,就是留個(gè)憑證
本文轉(zhuǎn)載自微信公眾號(hào)「猿天地」,作者尹吉?dú)g。轉(zhuǎn)載本文請(qǐng)聯(lián)系猿天地公眾號(hào)。
在多個(gè)團(tuán)隊(duì)之間的一些業(yè)務(wù)關(guān)聯(lián)上,內(nèi)部可以 Rpc 的方式進(jìn)行交互。某些業(yè)務(wù)其實(shí)不需要強(qiáng)關(guān)聯(lián),這個(gè)時(shí)候就會(huì)用消息隊(duì)列進(jìn)行解耦操作。比如下單后加積分,發(fā)短信通知的這類操作。
在用消息隊(duì)列的時(shí)候,我們最需要關(guān)注的一個(gè)問題就是消息會(huì)不會(huì)丟失?
這里的丟失指的就是要么你程序有問題,沒有發(fā)送出去。要么發(fā)送出去了,但是在某個(gè)節(jié)點(diǎn)上消息丟掉了,導(dǎo)致消費(fèi)方?jīng)]有收到你發(fā)送的消息,從而引發(fā)業(yè)務(wù)問題。
對(duì)于消息丟失,有很多的解決方案。本文不聊怎么在技術(shù)層面去防止消息丟失,聊另一個(gè)話題:消息到底發(fā)沒發(fā)送?
在多團(tuán)隊(duì)之間用消息解耦的場(chǎng)景下更容易出現(xiàn)這類問題,另一個(gè)團(tuán)隊(duì)的同學(xué)找你,說你們的消息是不是沒發(fā)送啊,我這邊這條數(shù)據(jù)的狀態(tài)沒流轉(zhuǎn),肯定沒收到消息。
然后你屁顛屁顛的去消息隊(duì)列的控制臺(tái)進(jìn)行消息的查詢,發(fā)現(xiàn)確實(shí)查不到。主要問題在于這條數(shù)據(jù)是幾個(gè)月之前的了,發(fā)送記錄沒有保存這么久,所以現(xiàn)在是有口難辯的這么一個(gè)狀態(tài)。
別人說你沒發(fā),但你自己又拿不出來證據(jù)來證明自己發(fā)送過了消息。所以這個(gè)鍋你只能自己背了。這就是今天要聊的話題,凡事要留個(gè)憑證,方便日后好追溯,特別是關(guān)鍵的業(yè)務(wù)場(chǎng)景。
存儲(chǔ)發(fā)送記錄到數(shù)據(jù)庫
既然要留憑證,那么就需要將憑證存儲(chǔ)起來。消息隊(duì)列的消息量大,肯定不會(huì)全部永久存儲(chǔ),一般都是存儲(chǔ)最近幾天的量,所以直接利用消息隊(duì)列去查有沒有發(fā)送只適合最近的消息,時(shí)間比較久的就無從追溯了。
在消息發(fā)送后,可以直接存儲(chǔ)到數(shù)據(jù)庫中,方便后面查詢發(fā)送記錄。其實(shí)就跟短信記錄一樣的,短信也經(jīng)常會(huì)遇到說這個(gè)短信我沒收到,是不是沒發(fā)送啊之類的問題。
存儲(chǔ)需要考慮的就是量的問題,如果你們每天的消息量很大,還需要存儲(chǔ)永久的數(shù)據(jù),那么就得拆分了,或者采用外置其他數(shù)據(jù)庫進(jìn)行單獨(dú)存儲(chǔ),比如 MongoDB 之類的 NoSql。
存儲(chǔ)發(fā)送記錄到日志
另一種方案就是發(fā)送后直接輸出一條日志即可,因?yàn)榇蟛糠止径加薪y(tǒng)一的日志平臺(tái),去收集日志進(jìn)行存儲(chǔ)。這個(gè)方案就不用占用 DB 的存儲(chǔ)或者說單獨(dú)弄一套 Nosql 存儲(chǔ),比較省事。
但是需要注意的是日志的存儲(chǔ)時(shí)間,像一些云廠商的日志服務(wù)是可以設(shè)置存儲(chǔ)時(shí)間的,因?yàn)槿罩镜牧吭酱?,成本越高?/p>
在很久之前就遇到過發(fā)消息其實(shí)是打印了日志的,但是存儲(chǔ)時(shí)間只有最近一個(gè)月。當(dāng)別人來問你消息有沒有發(fā)送的時(shí)候,你會(huì)發(fā)現(xiàn)當(dāng)時(shí)的日志已經(jīng)沒有了,所以我們還是需要進(jìn)行永久存儲(chǔ)。
永久存儲(chǔ)也就意味著成本的提高,其實(shí)我們可以將日志分類,普通的日志可以存儲(chǔ)時(shí)間短一點(diǎn),一些有用的日志可以單獨(dú)進(jìn)行輸出收集和永久存儲(chǔ)。這類日志的量相對(duì)少一點(diǎn),成本可控。
直接用本地消息表發(fā)送
除了用開源的消息隊(duì)列,很多公司也都會(huì)用本地消息表,單獨(dú)的消息服務(wù),基于數(shù)據(jù)庫設(shè)計(jì)的消息隊(duì)列這些形式來發(fā)送消息。這些形式的特點(diǎn)就是本身就基于 DB 做的持久化,所以對(duì)于查找有沒有發(fā)送過消息是天然支持的。當(dāng)然也有可能量大后即使分庫分表了,后期還是要擴(kuò)容或者定期歸檔,只要數(shù)據(jù)還在這個(gè)鍋就背不了。
關(guān)于作者:尹吉?dú)g,簡(jiǎn)單的技術(shù)愛好者,《Spring Cloud 微服務(wù)-全棧技術(shù)與案例解析》, 《Spring Cloud 微服務(wù) 入門 實(shí)戰(zhàn)與進(jìn)階》作者, 公眾號(hào)猿天地發(fā)起人。