<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>

          分布式事務(wù),缺陷方案咋那么多?

          共 1623字,需瀏覽 4分鐘

           ·

          2021-08-20 15:10

          說(shuō)到分布式事務(wù),可能很多時(shí)候想到的是支付轉(zhuǎn)賬、跨DB數(shù)據(jù)更新等典型的場(chǎng)景,但實(shí)際上,分布式事務(wù)是一個(gè)比高并發(fā)、高可用都普遍的多、幾乎無(wú)處不在的一個(gè)問(wèn)題。但因?yàn)橹匾暢潭炔粔?,?shí)際方案往往存在各種缺陷。


          無(wú)論大公司,還是小公司,都不太可能把所有數(shù)據(jù)都存在一個(gè)DB里面,用DB的單機(jī)事務(wù)完成。實(shí)際上,都不止一個(gè)系統(tǒng),系統(tǒng)之間需要接口互相調(diào)用。


          今天就舉個(gè)最簡(jiǎn)單的分布式事務(wù)例子:

          你的系統(tǒng),接收到用戶請(qǐng)求,需要更新自己的DB + 調(diào)用隔壁團(tuán)隊(duì)的一個(gè)http接口(做數(shù)據(jù)更新操作),并且2個(gè)操作必須保證數(shù)據(jù)一致性。

          (1) 是先調(diào)用別人接口,后更新DB,還是反過(guò)來(lái)?

          (2) 2個(gè)操作中,1個(gè)成功,1個(gè)失敗,給用戶是返回成功,還是失敗?


          先說(shuō)一下常用的缺陷方案:


          缺陷方案1:把接口調(diào)用包在DB事務(wù)里面

          調(diào)用接口成功,DB事務(wù)提交;調(diào)用接口失敗,DB事務(wù)回滾。看起來(lái)很正確,存在問(wèn)題:

          (1)接口超時(shí),那DB事務(wù)是應(yīng)該提交,還是回滾?答案:2個(gè)都不對(duì),不確定。

          (2)調(diào)用接口block,導(dǎo)致DB事務(wù)一直卡在那,鎖沒(méi)有辦法及時(shí)釋放。在并發(fā)量大的情況下,DB會(huì)被拖死。


          缺陷方案2:接口調(diào)用失敗,DB數(shù)據(jù)做逆向操作。

          先提交DB事務(wù),然后調(diào)用外部接口。如果接口調(diào)用失敗,DB數(shù)據(jù)再做邏輯上回滾。存在問(wèn)題:

          (1)同樣,接口如果不是失敗,是“超時(shí)”,也不確定DB是應(yīng)該回滾,還是提交。

          (2)DB邏輯回滾本身,是個(gè)網(wǎng)絡(luò)操作。也可能失敗/超時(shí),此時(shí)如何處理?


          缺陷方案3:接口調(diào)用失敗,插入異常表,再事后回補(bǔ)。

          先提交DB事務(wù),然后調(diào)用外部接口。如果接口調(diào)用失敗,往異常表插入1條記錄,然后事后根據(jù)異常表里面的記錄,去重試外部接口。存在問(wèn)題:

          同上面一樣,插入異常表,是個(gè)網(wǎng)絡(luò)操作,也沒(méi)辦法保證這個(gè)一定成功。


          缺陷方案4:接口調(diào)用失敗,往Kafka里面插入一條異常消息,消費(fèi)消息做事后回補(bǔ)。


          同方案3一樣,插入異常消息也是個(gè)網(wǎng)絡(luò)操作,有可能超時(shí)/失敗。



          正確的策略1:部分成功時(shí),給調(diào)用方返回失敗。讓調(diào)用方重試,被調(diào)方冪等

          無(wú)論是先調(diào)用外部接口,后更新DB,還是反過(guò)來(lái),只要任何一個(gè)超時(shí),給用戶返回的不是“成功”,也不是“失敗”,而是“不確定”。

          所謂“不確定”,就是類(lèi)似“目前網(wǎng)絡(luò)繁忙,請(qǐng)稍候再次確認(rèn)。有可能之前的更新成功了,也有可能更新失敗了“。

          所以,無(wú)論是DB更新,還是接口調(diào)用,都要保證冪等。


          正確的策略2:部分成功時(shí),給調(diào)用方返回成功。然后做最終一致性保證。

          先更新DB,后調(diào)用外部接口。不管接口結(jié)果如何,只要DB成功了,就給用戶返回成功。

          如果接口調(diào)用失敗/超時(shí),重試3次之后,仍然失敗/超時(shí)。那往異常表插入1條記錄,事后再去根據(jù)異常表做補(bǔ)償。

          但異常表本身有可能插入失敗,所以需要一個(gè)”對(duì)賬任務(wù)“去做兜底,不斷掃描DB,對(duì)于DB中的每條記錄,查詢(xún)對(duì)應(yīng)的外部接口是否更新成功,如果沒(méi)有更新成功,不斷重試,直到成功。重試N次之后,還不行,告警人工處理。

          ”對(duì)賬任務(wù)“可以是增量的,根據(jù)DB中數(shù)據(jù)的update_time,定期對(duì)賬。


          正確的策略3:DB成功了,就返回成功。然后異步去調(diào)外部接口,最終一致性。

          DB成功了,就對(duì)用戶返回成功。然后一個(gè)后臺(tái)任務(wù),不斷去掃描DB,調(diào)對(duì)應(yīng)的外部接口。接口失敗/超時(shí),后臺(tái)任務(wù)可以無(wú)限次重試,直到最終2者一致。同樣,超過(guò)N次之后,還不一致,告警人工處理。


          最后總結(jié):因?yàn)榫W(wǎng)絡(luò)調(diào)用”超時(shí)“是不可避免的,超時(shí)后結(jié)果是”不確定“的。不管怎么做,都沒(méi)有辦法在1次用戶請(qǐng)求中,保證2次網(wǎng)絡(luò)調(diào)用同時(shí)成功。所以,要么”調(diào)用方有無(wú)限次重試 + 告警人工修補(bǔ)機(jī)制”,要么“被調(diào)方有無(wú)限次重試 + 告警人工修補(bǔ)機(jī)制”,也就是“對(duì)賬兜底”。



          瀏覽 52
          點(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>
                  日韩中AV无码毛片 | 51妺嘿嘿午夜福利视频 | 久久人人妻人人做人人玩精品 | 婷婷在线成人视频精品 | 波多野结衣国产 |