<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          我覺得這個(gè)功能不用實(shí)現(xiàn)

          共 3807字,需瀏覽 8分鐘

           ·

          2023-02-28 09:58

          我們?cè)谑褂?code style="font-size:14px;color:rgb(30,107,184);background-color:rgba(27,31,35,.05);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;">mq的時(shí)候,就會(huì)很自然思考一個(gè)問題:怎么保證數(shù)據(jù)不丟失?

          現(xiàn)在austin接入層是把消息發(fā)到mq,下發(fā)邏輯層從mq消費(fèi)數(shù)據(jù),隨后調(diào)用對(duì)應(yīng)渠道接口來下發(fā)消息。

          1a87a85daeedc5a528e85958e1403904.webp

          消息丟棄一般我們考慮的是消費(fèi)端,于是重點(diǎn)看的是下發(fā)邏輯層。

          (因?yàn)閷?duì)于mq使用方來說:生產(chǎn)端只要配置mq相關(guān)的參數(shù),在調(diào)用下發(fā)時(shí)有回調(diào)重試機(jī)制。那就足夠了,生產(chǎn)端能做的東西確實(shí)不多)

          目前為止,下發(fā)邏輯層(消費(fèi)端)使用的是自動(dòng)提交offset策略。只要消費(fèi)端存在系統(tǒng)重啟或者進(jìn)程被kill掉,那就會(huì)有丟消息的情況。

                
                spring.kafka.consumer.enable-auto-commit=true

          當(dāng)前下發(fā)邏輯層(消費(fèi)端)有可能放大了這個(gè)丟棄消息的問題,因?yàn)楝F(xiàn)在是消費(fèi)到mq數(shù)據(jù)后,會(huì)把消息給到線程池去處理。線程池會(huì)指定一個(gè)阻塞隊(duì)列,那隊(duì)列數(shù)量越大,可能由重啟所丟棄的消息就越多

          fdd67d516cdcae4817baeedf1ec9ab70.webp

          這里我的策略是:當(dāng)應(yīng)用重啟的時(shí)候,系統(tǒng)里的線程池是優(yōu)雅關(guān)閉的(盡可能等待一段時(shí)間,等阻塞隊(duì)列里沒有消息了,再關(guān)閉線程池)。

          但回到問題的本質(zhì)上,只要消費(fèi)端是自動(dòng)提交offset策略,就一定會(huì)有丟消息的問題。所以要做到消費(fèi)端的消息不丟,我們就要設(shè)置為手動(dòng)提交offset,這個(gè)是必要條件。

          有沒有必要保證不丟

          在探討具體的技術(shù)實(shí)現(xiàn)方案之前,我們來看看在業(yè)務(wù)上有沒有必要保證消息不丟。我剛接觸到消息推送平臺(tái)的時(shí)候,當(dāng)時(shí)那個(gè)交接的哥們告訴我和我學(xué)長(zhǎng):消息少發(fā)比多發(fā)要好。

          1、重要的消息用戶很可能會(huì)手動(dòng)重試觸發(fā)。

          austin是一個(gè)發(fā)送各類渠道消息的平臺(tái),從我的經(jīng)驗(yàn)來說,這里面最重要的是短信渠道。經(jīng)過austin下發(fā)很可能是登陸驗(yàn)證碼,銀行卡提現(xiàn)驗(yàn)證碼,這類消息從全局上看是最重要的。

          而其他渠道,例如push通知欄的通知消息,微信渠道的營(yíng)銷消息,這種消息即便用戶沒收到,也不會(huì)對(duì)用戶帶來很大的使用體驗(yàn)問題。這種消息或許對(duì)絕大數(shù)用戶都是無感知的(少發(fā)幾條,用戶可能更樂意)。

          我們先假設(shè)用戶的某一次銀行卡提現(xiàn)的驗(yàn)證碼恰好因?yàn)槲覀冎貑⑾到y(tǒng)而丟棄。這時(shí)候,絕大數(shù)用戶可能懷疑自己的信號(hào)問題,會(huì)繼續(xù)操作,重新發(fā)送一次。

          (因?yàn)榭头?jīng)常找我排查這種問題,每次都能看到有好幾條下發(fā)記錄。當(dāng)然了,能到技術(shù)的,99%的問題都不是由系統(tǒng)重啟丟失消息導(dǎo)致的,更多可能是用戶的客戶端本身確實(shí)就存在問題)

          2、消息是有時(shí)效性的。比如驗(yàn)證碼這種短信一般就5min的時(shí)效性,由于系統(tǒng)的問題,你超過這個(gè)時(shí)間給用戶發(fā)送,對(duì)用戶的體驗(yàn)是非常差的。

          3、消息推送平臺(tái)是有全鏈路追蹤的,是可以知道下發(fā)的消息有沒有到達(dá)到用戶手上,至少都可以知道在我們的系統(tǒng)內(nèi)部執(zhí)行過程中有沒有丟。如果這條消息真的那么重要,那可以單獨(dú)為丟棄的消息單獨(dú)做重發(fā)處理,這些功能在消息推送平臺(tái)都是支持的。

          25cd4e6a51f2eb79dae24b761a95591f.webp

          這個(gè)問題我以前的同事也跟我探討過,就是把上面的內(nèi)容給我隔壁的老哥聽的,他說:你就盡扯淡吧,到面試的時(shí)候人家可不認(rèn)你,丟了就是丟了,其他都是借口

          我說:沒事,要是不認(rèn)的話,就把我們處理訂單那一套給他講講嘛,反正處理的思路都是一樣的。

          不過啊,廣告訂單邏輯處理又相對(duì)沒那么復(fù)雜,廣告訂單最后是以入數(shù)據(jù)庫作為標(biāo)準(zhǔn)的,又可以接受一定的延遲,只要能保證處理完就行了。

          要想client端消費(fèi)數(shù)據(jù)不能丟,肯定是不能使用autoCommit的,所以必須是手動(dòng)提交的。

          43c8173b3f3dc59d481a45e9f24f16a8.webp

          候選者:我們這邊是這樣實(shí)現(xiàn)的:

          候選者:一、從Kafka拉取消息(一次批量拉取500條,這里主要看配置)時(shí)

          候選者:二、為每條拉取的消息分配一個(gè)msgId(遞增)

          候選者:三、將msgId存入內(nèi)存隊(duì)列(sortSet)中

          候選者:四、使用Map存儲(chǔ)msgId與msg(有offset相關(guān)的信息)的映射關(guān)系,通過msgId用來獲取相關(guān)元信息

          候選者:五、當(dāng)業(yè)務(wù)處理完消息后,ack時(shí),獲取當(dāng)前處理的消息msgId,然后從sortSet刪除該msgId(此時(shí)代表已經(jīng)處理過了)

          候選者:六、接著與sortSet隊(duì)列(本地內(nèi)存隊(duì)列)的首部第一個(gè)Id比較(其實(shí)就是最小的msgId),如果當(dāng)前msgId<=sort Set第一個(gè)ID,則提交當(dāng)前offset

          候選者:七、系統(tǒng)即便掛了,在下次重啟時(shí)就會(huì)從sortSet隊(duì)首的消息開始拉取,實(shí)現(xiàn)至少處理一次語義

          候選者:八、會(huì)有少量的消息重復(fù),但只要下游做好冪等就OK了。

          db81093460c18f59cffc845503812543.webp

          面試官:嗯,你也提到了冪等,你們這業(yè)務(wù)怎么實(shí)現(xiàn)冪等性的呢?

          候選者:嗯,還是以處理訂單消息為例好了。

          候選者:冪等Key我們由訂單編號(hào)+訂單狀態(tài)所組成(一筆訂單的狀態(tài)只會(huì)處理一次)

          候選者:在處理之前,我們首先會(huì)去查Redis是否存在該Key,如果存在,則說明我們已經(jīng)處理過了,直接丟掉

          候選者:如果Redis沒處理過,則繼續(xù)往下處理,最終的邏輯是將處理過的數(shù)據(jù)插入到業(yè)務(wù)DB上,再到最后把冪等Key插入到Redis上

          候選者:顯然,單純通過Redis是無法保證冪等的(:

          候選者:所以,Redis其實(shí)只是一個(gè)「前置」處理,最終的冪等性是依賴數(shù)據(jù)庫的唯一Key來保證的(唯一Key實(shí)際上也是訂單編號(hào)+狀態(tài))

          候選者:總的來說,就是通過Redis做前置處理,DB唯一索引做最終保證來實(shí)現(xiàn)冪等性的

          e2cc6de8b3958a0daf1cccd8463e5c37.webp

          保證austin數(shù)據(jù)不丟需要做什么?

          保證數(shù)據(jù)不丟簡(jiǎn)單來說,就是我們要在消費(fèi)端手動(dòng)ack offset,不能再用自動(dòng)提交策略了。這樣當(dāng)我們系統(tǒng)重啟時(shí),kafka會(huì)自動(dòng)從未ackoffset中拉取。

          如果要實(shí)現(xiàn)消息推送平臺(tái)不丟消息的話,有幾個(gè)問題是需要考慮的:

          1、消息少發(fā)比多發(fā)要好,那么要實(shí)現(xiàn)消息不丟,就必須要在系統(tǒng)內(nèi)實(shí)現(xiàn)冪等。因?yàn)楝F(xiàn)在的消息不丟,一般都是基于【至少一次]消費(fèi)語義去做的。

          2、那實(shí)現(xiàn)冪等的邏輯是在調(diào)用渠道下發(fā)接口前,還是渠道下發(fā)接口后?

          如果做在下發(fā)接口前,那是不是會(huì)有可能第一次下發(fā)記錄寫入了,但實(shí)際調(diào)用下發(fā)接口卻失敗了,后面的重試都被冪等處理掉了。

          如果做在下發(fā)接口后,那是不是會(huì)有可能調(diào)用調(diào)用下發(fā)接口成功了,但寫入冪等處理的消息失敗了,后面的重試就會(huì)導(dǎo)致消息多發(fā)

          3、消息是有時(shí)效性的,那如果重試的處理時(shí)間過長(zhǎng),那是不是要考慮把這條消息給丟棄掉,不再重試了。

          4、重試的消息不應(yīng)該影響到正常消息的下發(fā),他得作為一種補(bǔ)償?shù)臋C(jī)制,而非主流程。

          稍微細(xì)想下技術(shù)實(shí)現(xiàn),應(yīng)該不太好搞,還有很多細(xì)節(jié)的地方得關(guān)注到。比如業(yè)務(wù)上的:應(yīng)該是不需要所有的渠道的所有類型消息都得實(shí)現(xiàn)消息不丟吧?現(xiàn)在的設(shè)計(jì)是追求高性能的,能在短時(shí)間內(nèi)下發(fā)批量的消息。而如果做到所有消息不丟,肯定會(huì)影響到下發(fā)的速率

          什么時(shí)候動(dòng)手?

          1、對(duì)于這個(gè)功能吧,有用肯定是有用,但這功能又沒那么急

          2、我估摸對(duì)現(xiàn)有代碼改動(dòng)還是蠻大的,現(xiàn)在我還沒想好該怎么實(shí)現(xiàn)比較好,也一直沒下手。

          3、最近工作的事挺多的,沒那么有空

          結(jié)論:先看看想要這個(gè)功能的人多不多,不多就鴿一會(huì)。

          都看到這了,如果按上面的理由,我不實(shí)現(xiàn)這個(gè)功能,你認(rèn)不認(rèn)可?

          推薦項(xiàng)目

          如果想學(xué)Java項(xiàng)目的,我還是 強(qiáng)烈推薦 我的開源項(xiàng)目消息推送平臺(tái)Austin,可以用作 畢業(yè)設(shè)計(jì) ,可以用作 校招 ,可以看看 生產(chǎn)環(huán)境是怎么推送消息 的。

          倉庫地址(可點(diǎn)擊閱讀原文跳轉(zhuǎn)):https://gitee.com/zhongfucheng/austin

          我開通了 股東服務(wù) 內(nèi)容,感興趣可以點(diǎn)擊下方看看,主要針對(duì)的是項(xiàng)目喲

          VIP服務(wù)

          瀏覽 124
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91丨国产丨白浆秘 在线 | 日韩一区二区三区视频在线观看 | 日日夜夜久久视频久久视频 | 色播五月婷婷网 | 黄色片网站视频看免费在线 |