成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

分布式系統遇到的十個問題

開發 新聞
不管是招初級軟件工程師還是高級,都會要求懂分布式,甚至要求用過。

前言

我們都在討論分布式,特別是面試的時候,不管是招初級軟件工程師還是高級,都會要求懂分布式,甚至要求用過。傳得沸沸揚揚的分布式到底是什么東東,有什么優勢?

借用火影忍術

圖片

風遁·螺旋手里劍

看過火影的同學肯定知道漩渦鳴人的招牌忍術:多重影分身之術。

  • 這個術有一個特別厲害的地方,過程和心得:多個分身的感受和經歷都是相通的。比如 A 分身去找卡卡西(鳴人的老師)請教問題,那么其他分身也會知道 A 分身問的什么問題。
  • 漩渦鳴人?有另外一個超級厲害的忍術,需要由幾個影分身完成:風遁·螺旋手里劍。這個忍術是靠三個鳴人一起協作完成的。

這兩個忍術和分布式有什么關系?

  • 分布在不同地方的系統或服務,是彼此相互關聯的。
  • 分布式系統是分工合作的。

案例:

  • 比如 Redis 的哨兵機制?,可以知道集群環境下哪臺Redis 節點掛了。
  • Kafka的Leader 選舉機制?,如果某個節點掛了,會從follower 中重新選舉一個 leader 出來。(leader 作為寫數據的入口,follower 作為讀的入口)

那多重影分身之術有什么缺點?

  • 會消耗大量的查克拉。分布式系統同樣具有這個問題,需要幾倍的資源來支持。

對分布式的通俗理解

  • 是一種工作方式
  • 若干獨立計算機的集合,這些計算機對于用戶來說就像單個相關系統
  • 將不同的業務分布在不同的地方

優勢可以從兩方面考慮:一個是宏觀,一個是微觀。

  • 宏觀層面:多個功能模塊糅合在一起的系統進行服務拆分,來解耦服務間的調用。
  • 微觀層面:將模塊提供的服務分布到不同的機器或容器里,來擴大服務力度。

任何事物有陰必有陽,那分布式又會帶來哪些問題呢?

  • 需要更多優質人才懂分布式,人力成本增加
  • 架構設計變得異常復雜,學習成本高
  • 運維部署和維護成本顯著增加
  • 多服務間鏈路變長,開發排查問題難度加大
  • 環境高可靠性問題
  • 數據冪等性問題
  • 數據的順序問題
  • 等等

講到分布式不得不知道 CAP 定理和 Base 理論,這里給不知道的同學做一個掃盲。

CAP 定理

在理論計算機科學中,CAP 定理指出對于一個分布式計算系統來說,不可能通是滿足以下三點:

  • 一致性(Consistency)
  • 所有節點訪問同一份最新的數據副本。
  • 可用性(Availability)
  • 每次請求都能獲取到非錯的響應,但不保證獲取的數據為最新數據
  • 分區容錯性(Partition tolerance)
  • 不能在時限內達成數據一致性,就意味著發生了分區的情況,必須就當前操作在 C 和 A 之間做出選擇)

BASE 理論

BASE 是 Basically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent(最終一致性)三個短語的縮寫。BASE 理論是對 CAP 中 AP 的一個擴展,通過犧牲強一致性來獲得可用性,當出現故障允許部分不可用但要保證核心功能可用,允許數據在一段時間內是不一致的,但最終達到一致狀態。滿足 BASE 理論的事務,我們稱之為柔性事務。

  • 基本可用 :分布式系統在出現故障時,允許損失部分可用功能,保證核心功能可用。如電商網址交易付款出現問題來,商品依然可以正常瀏覽。
  • 軟狀態:由于不要求強一致性,所以BASE允許系統中存在中間狀態(也叫軟狀態),這個狀態不影響系統可用性,如訂單中的“支付中”、“數據同步中”等狀態,待數據最終一致后狀態改為“成功”狀態。
  • 最終一致性:最終一致是指的經過一段時間后,所有節點數據都將會達到一致。如訂單的“支付中”狀態,最終會變為“支付成功”或者“支付失敗”,使訂單狀態與實際交易結果達成一致,但需要一定時間的延遲、等待。

一、分布式消息隊列的坑

消息隊列如何做分布式?

將消息隊列里面的消息分攤到多個節點(指某臺機器或容器)上,所有節點的消息隊列之和就包含了所有消息。

1. 消息隊列的坑之非冪等

冪等性概念

所謂冪等性就是無論多少次操作和第一次的操作結果一樣。如果消息被多次消費,很有可能造成數據的不一致。而如果消息不可避免地被消費多次,如果我們開發人員能通過技術手段保證數據的前后一致性,那也是可以接受的,這讓我想起了 Java 并發編程中的 ABA 問題,如果出現了 [??ABA問題??),若能保證所有數據的前后一致性也能接受。

場景分析

RabbitMQ、RocketMQ、Kafka 消息隊列中間件都有可能出現消息重復消費問題。這種問題并不是 MQ 自己保證的,而是需要開發人員來保證。

這幾款消息隊列中間都是是全球最牛的分布式消息隊列,那肯定考慮到了消息的冪等性。我們以 Kafka 為例,看看 Kafka 是怎么保證消息隊列的冪等性。

Kafka 有一個 偏移量 的概念,代表著消息的序號,每條消息寫到消息隊列都會有一個偏移量,消費者消費了數據之后,每過一段固定的時間,就會把消費過的消息的偏移量提交一下,表示已經消費過了,下次消費就從偏移量后面開始消費。

坑:當消費完消息后,還沒來得及提交偏移量,系統就被關機了,那么未提交偏移量的消息則會再次被消費。

如下圖所示,隊列中的數據 A、B、C,對應的偏移量分別為 100、101、102,都被消費者消費了,但是只有數據 A 的偏移量 100 提交成功,另外 2 個偏移量因系統重啟而導致未及時提交。

圖片系統重啟,偏移量未提交

重啟后,消費者又是拿偏移量 100 以后的數據,從偏移量 101 開始拿消息。所以數據 B 和數據 C 被重復消息。

如下圖所示:

圖片重啟后,重復消費消息

避坑指南

  • 微信支付結果通知場景

微信官方文檔上提到微信支付通知結果可能會推送多次,需要開發者自行保證冪等性。第一次我們可以直接修改訂單狀態(如支付中 -> 支付成功),第二次就根據訂單狀態來判斷,如果不是支付中,則不進行訂單處理邏輯。

  • 插入數據庫場景
  • 每次插入數據時,先檢查下數據庫中是否有這條數據的主鍵 id,如果有,則進行更新操作。
  • 寫 Redis 場景
  • Redis 的 Set 操作天然冪等性,所以不用考慮 Redis 寫數據的問題。
  • 其他場景方案
  • 生產者發送每條數據時,增加一個全局唯一 id,類似訂單 id。每次消費時,先去 Redis 查下是否有這個 id,如果沒有,則進行正常處理消息,且將 id 存到 Redis。如果查到有這個 id,說明之前消費過,則不要進行重復處理這條消息。
  • 不同業務場景,可能會有不同的冪等性方案,大家選擇合適的即可,上面的幾種方案只是提供常見的解決思路。

2. 消息隊列的坑之消息丟失

坑:消息丟失會帶來什么問題?如果是訂單下單、支付結果通知、扣費相關的消息丟失,則可能造成財務損失,如果量很大,就會給甲方帶來巨大損失。

那消息隊列是否能保證消息不丟失呢?答案:否。主要有三種場景會導致消息丟失。

圖片

消息隊列之消息丟失

(1)生產者存放消息的過程中丟失消息

圖片

生產者丟失消息

解決方案

  • 事務機制(不推薦,異步方式)

對于 RabbitMQ 來說,生產者發送數據之前開啟 RabbitMQ 的事務機制channel.txselect ,如果消息沒有進隊列,則生產者受到異常報錯,并進行回滾 channel.txRollback,然后重試發送消息;如果收到了消息,則可以提交事務 channel.txCommit。但這是一個同步的操作,會影響性能。

  • confirm 機制(推薦,異步方式)

我們可以采用另外一種模式:confirm 模式來解決同步機制的性能問題。每次生產者發送的消息都會分配一個唯一的 id,如果寫入到了 RabbitMQ 隊列中,則 RabbitMQ 會回傳一個 ack 消息,說明這個消息接收成功。如果 RabbitMQ 沒能處理這個消息,則回調 nack 接口。說明需要重試發送消息。

也可以自定義超時時間 + 消息 id 來實現超時等待后重試機制。但可能出現的問題是調用 ack 接口時失敗了,所以會出現消息被發送兩次的問題,這個時候就需要保證消費者消費消息的冪等性。

事務模式 和 confirm 模式的區別:

  • 事務機制是同步的,提交事務后悔被阻塞直到提交事務完成后。
  • confirm 模式異步接收通知,但可能接收不到通知。需要考慮接收不到通知的場景。

(2)消息隊列丟失消息

圖片

消息隊列丟失消息

消息隊列的消息可以放到內存中,或將內存中的消息轉到硬盤(比如數據庫)中,一般都是內存和硬盤中都存有消息。如果只是放在內存中,那么當機器重啟了,消息就全部丟失了。如果是硬盤中,則可能存在一種極端情況,就是將內存中的數據轉換到硬盤的期間中,消息隊列出問題了,未能將消息持久化到硬盤。

解決方案

  • 創建Queue 的時候將其設置為持久化。
  • 發送消息的時候將消息的deliveryMode 設置為 2 。
  • 開啟生產者confirm 模式,可以重試發送消息。

(3)消費者丟失消息

圖片

消費者丟失消息

消費者剛拿到數據,還沒開始處理消息,結果進程因為異常退出了,消費者沒有機會再次拿到消息。

解決方案

  • 關閉 RabbitMQ 的自動ack?,每次生產者將消息寫入消息隊列后,就自動回傳一個ack 給生產者。
  • 消費者處理完消息再主動ack,告訴消息隊列我處理完了。

問題: 那這種主動 ack 有什么漏洞了?如果 主動 ack 的時候掛了,怎么辦?

則可能會被再次消費,這個時候就需要冪等處理了。

問題: 如果這條消息一直被重復消費怎么辦?

則需要有加上重試次數的監測,如果超過一定次數則將消息丟失,記錄到異常表或發送異常通知給值班人員。

(4)RabbitMQ 消息丟失總結

圖片RabbitMQ 丟失消息的處理方案

(5)Kafka 消息丟失

場景:Kafka 的某個 broker(節點)宕機了,重新選舉 leader (寫入的節點)。如果 leader 掛了,follower 還有些數據未同步完,則 follower 成為 leader 后,消息隊列會丟失一部分數據。

解決方案

  • 給 topic 設置replication.factor 參數,值必須大于 1,要求每個 partition 必須有至少 2 個副本。
  • 給 kafka 服務端設置min.insyc.replicas 必須大于 1,表示一個 leader 至少一個 follower 還跟自己保持聯系。

3. 消息隊列的坑之消息亂序

坑: 用戶先下單成功,然后取消訂單,如果順序顛倒,則最后數據庫里面會有一條下單成功的訂單。

RabbitMQ 場景:

  • 生產者向消息隊列按照順序發送了 2 條消息,消息1:增加數據 A,消息2:刪除數據 A。
  • 期望結果:數據 A 被刪除。
  • 但是如果有兩個消費者,消費順序是:消息2、消息 1。則最后結果是增加了數據 A。

圖片

RabbitMQ消息亂序場景

圖片

RabbitMQ 消息亂序場景

RabbitMQ 解決方案:

  • 將 Queue 進行拆分,創建多個內存 Queue,消息 1 和 消息 2 進入同一個 Queue。
  • 創建多個消費者,每一個消費者對應一個 Queue。

圖片

RabbitMQ 解決方案

Kafka 場景:

  • 創建了 topic,有 3 個 partition。
  • 創建一條訂單記錄,訂單 id 作為 key,訂單相關的消息都丟到同一個 partition 中,同一個生產者創建的消息,順序是正確的。
  • 為了快速消費消息,會創建多個消費者去處理消息,而為了提高效率,每個消費者可能會創建多個線程來并行的去拿消息及處理消息,處理消息的順序可能就亂序了。

圖片

Kafka 消息丟失場景

Kafka 解決方案:

  • 解決方案和 RabbitMQ 類似,利用多個 內存 Queue,每個線程消費 1個 Queue。
  • 具有相同 key 的消息 進同一個 Queue。

圖片

Kafka 消息亂序解決方案

4. 消息隊列的坑之消息積壓

消息積壓:消息隊列里面有很多消息來不及消費。

場景 1: 消費端出了問題,比如消費者都掛了,沒有消費者來消費了,導致消息在隊列里面不斷積壓。

場景 2: 消費端出了問題,比如消費者消費的速度太慢了,導致消息不斷積壓。

坑:比如線上正在做訂單活動,下單全部走消息隊列,如果消息不斷積壓,訂單都沒有下單成功,那么將會損失很多交易。

圖片

消息隊列之消息積壓

解決方案:解鈴還須系鈴人

  • 修復代碼層面消費者的問題,確保后續消費速度恢復或盡可能加快消費的速度。
  • 停掉現有的消費者。
  • 臨時建立好原先 5 倍的 Queue 數量。
  • 臨時建立好原先 5 倍數量的 消費者。
  • 將堆積的消息全部轉入臨時的 Queue,消費者來消費這些 Queue。

圖片

消息積壓解決方案

5. 消息隊列的坑之消息過期失效

坑:RabbitMQ 可以設置過期時間,如果消息超過一定的時間還沒有被消費,則會被 RabbitMQ 給清理掉。消息就丟失了。

圖片

消息過期失效

解決方案:

  • 準備好批量重導的程序
  • 手動將消息閑時批量重導

圖片

消息過期失效解決方案

6. 消息隊列的坑之隊列寫滿

坑:當消息隊列因消息積壓導致的隊列快寫滿,所以不能接收更多的消息了。生產者生產的消息將會被丟棄。

解決方案:

  • 判斷哪些是無用的消息,RabbitMQ 可以進行Purge Message 操作。
  • 如果是有用的消息,則需要將消息快速消費,將消息里面的內容轉存到數據庫。
  • 準備好程序將轉存在數據庫中的消息再次重導到消息隊列。

閑時重導消息到消息隊列。

二、分布式緩存的坑

在高頻訪問數據庫的場景中,我們會在業務層和數據層之間加入一套緩存機制,來分擔數據庫的訪問壓力,畢竟訪問磁盤 I/O 的速度是很慢的。比如利用緩存來查數據,可能5ms就能搞定,而去查數據庫可能需要 50 ms,差了一個數量級。而在高并發的情況下,數據庫還有可能對數據進行加鎖,導致訪問數據庫的速度更慢。

分布式緩存我們用的最多的就是 Redis了,它可以提供分布式緩存服務。

1. Redis 數據丟失的坑

哨兵機制

Redis 可以實現利用哨兵機制實現集群的高可用。那什么十哨兵機制呢?

  • 英文名:sentinel?,中文名:哨兵。
  • 集群監控:負責主副進程的正常工作。
  • 消息通知:負責將故障信息報警給運維人員。
  • 故障轉移:負責將主節點轉移到備用節點上。
  • 配置中心:通知客戶端更新主節點地址。
  • 分布式:有多個哨兵分布在每個主備節點上,互相協同工作。
  • 分布式選舉:需要大部分哨兵都同意,才能進行主備切換。
  • 高可用:即使部分哨兵節點宕機了,哨兵集群還是能正常工作。

坑: 當主節點發生故障時,需要進行主備切換,可能會導致數據丟失。

異步復制數據導致的數據丟失

主節點異步同步數據給備用節點的過程中,主節點宕機了,導致有部分數據未同步到備用節點。而這個從節點又被選舉為主節點,這個時候就有部分數據丟失了。

腦裂導致的數據丟失

主節點所在機器脫離了集群網絡,實際上自身還是運行著的。但哨兵選舉出了備用節點作為主節點,這個時候就有兩個主節點都在運行,相當于兩個大腦在指揮這個集群干活,但到底聽誰的呢?這個就是腦裂。

那怎么腦裂怎么會導致數據丟失呢?如果發生腦裂后,客戶端還沒來得及切換到新的主節點,連的還是第一個主節點,那么有些數據還是寫入到了第一個主節點里面,新的主節點沒有這些數據。那等到第一個主節點恢復后,會被作為備用節點連到集群環境,而且自身數據會被清空,重新從新的主節點復制數據。而新的主節點因沒有客戶端之前寫入的數據,所以導致數據丟失了一部分。

避坑指南

  • 配置 min-slaves-to-write 1,表示至少有一個備用節點。
  • 配置 min-slaves-max-lag 10,表示數據復制和同步的延遲不能超過 10 秒。最多丟失 10 秒的數據

注意:緩存雪崩、緩存穿透、緩存擊穿并不是分布式所獨有的,單機的時候也會出現。所以不在分布式的坑之列。

三、分庫分表的坑

1.分庫分表的坑之擴容

分庫、分表、垂直拆分和水平拆分

  • 分庫:因一個數據庫支持的最高并發訪問數是有限的,可以將一個數據庫的數據拆分到多個庫中,來增加最高并發訪問數。
  • 分表:因一張表的數據量太大,用索引來查詢數據都搞不定了,所以可以將一張表的數據拆分到多張表,查詢時,只用查拆分后的某一張表,SQL 語句的查詢性能得到提升。
  • 分庫分表優勢:分庫分表后,承受的并發增加了多倍;磁盤使用率大大降低;單表數據量減少,SQL 執行效率明顯提升。
  • 水平拆分:把一個表的數據拆分到多個數據庫,每個數據庫中的表結構不變。用多個庫抗更高的并發。比如訂單表每個月有500萬條數據累計,每個月都可以進行水平拆分,將上個月的數據放到另外一個數據庫。
  • 垂直拆分:把一個有很多字段的表,拆分成多張表到同一個庫或多個庫上面。高頻訪問字段放到一張表,低頻訪問的字段放到另外一張表。利用數據庫緩存來緩存高頻訪問的行數據。比如將一張很多字段的訂單表拆分成幾張表分別存不同的字段(可以有冗余字段)。
  • 分庫、分表的方式:

根據租戶來分庫、分表。

利用時間范圍來分庫、分表。

利用 ID 取模來分庫、分表。

坑:分庫分表是一個運維層面需要做的事情,有時會采取凌晨宕機開始升級。可能熬夜到天亮,結果升級失敗,則需要回滾,其實對技術團隊都是一種煎熬。

怎么做成自動的來節省分庫分表的時間?

  • 雙寫遷移方案:遷移時,新數據的增刪改操作在新庫和老庫都做一遍。
  • 使用分庫分表工具 Sharding-jdbc  來完成分庫分表的累活。
  • 使用程序來對比兩個庫的數據是否一致,直到數據一致。

坑: 分庫分表看似光鮮亮麗,但分庫分表會引入什么新的問題呢?

垂直拆分帶來的問題

  • 依然存在單表數據量過大的問題。
  • 部分表無法關聯查詢,只能通過接口聚合方式解決,提升了開發的復雜度。
  • 分布式事處理復雜。

水平拆分帶來的問題

  • 跨庫的關聯查詢性能差。
  • 數據多次擴容和維護量大。
  • 跨分片的事務一致性難以保證。

2.分庫分表的坑之唯一 ID

為什么分庫分表需要唯一 ID

  • 如果要做分庫分表,則必須得考慮表主鍵 ID 是全局唯一的,比如有一張訂單表,被分到 A 庫和 B 庫。如果 兩張訂單表都是從 1 開始遞增,那查詢訂單數據時就錯亂了,很多訂單 ID 都是重復的,而這些訂單其實不是同一個訂單。
  • 分庫的一個期望結果就是將訪問數據的次數分攤到其他庫,有些場景是需要均勻分攤的,那么數據插入到多個數據庫的時候就需要交替生成唯一的 ID 來保證請求均勻分攤到所有數據庫。

坑: 唯一 ID 的生成方式有 n 種,各有各的用途,別用錯了。

生成唯一 ID 的原則

  • 全局唯一性
  • 趨勢遞增
  • 單調遞增
  • 信息安全

生成唯一 ID 的幾種方式

  • 數據庫自增 ID。每個數據庫每增加一條記錄,自己的 ID 自增 1。

     多個庫的 ID 可能重復,這個方案可以直接否掉了,不適合分庫分表后的 ID 生成。

     信息不安全

     缺點

  • 適用 UUID 唯一 ID。

     UUID 太長、占用空間大。

     不具有有序性,作為主鍵時,在寫入數據時,不能產生有順序的 append 操作,只能進行 insert 操作,導致讀取整個 B+ 樹節點到內存,插入記錄后將整個節點寫回磁盤,當記錄占用空間很大的時候,性能很差。

     缺點

  • 獲取系統當前時間作為唯一 ID。

     高并發時,1 ms內可能有多個相同的 ID。

     信息不安全

     缺點

  • Twitter 的 snowflake(雪花算法):Twitter 開源的分布式 id 生成算法,64 位的 long 型的 id,分為 4 部分

圖片

snowflake 算法

基本原理和優缺點:

1 bit:不用,統一為 0

41 bits:毫秒時間戳,可以表示 69 年的時間。

10 bits:5 bits 代表機房 id,5 個 bits 代表機器 id。最多代表 32 個機房,每個機房最多代表 32 臺機器。

12 bits:同一毫秒內的 id,最多 4096 個不同 id,自增模式。

優點:

毫秒數在高位,自增序列在低位,整個ID都是趨勢遞增的。

? 不依賴數據庫等第三方系統,以服務的方式部署,穩定性更高,生成ID的性能也是非常高的。

? 可以根據自身業務特性分配bit位,非常靈活。

缺點:

? 強依賴機器時鐘,如果機器上時鐘回撥(可以搜索 2017 年閏秒 7:59:60),會導致發號重復或者服務會處于不可用狀態。

百度的 UIDGenerator 算法。

  • 基于 Snowflake 的優化算法。
  • 借用未來時間和雙 Buffer 來解決時間回撥與生成性能等問題,同時結合 MySQL 進行 ID 分配。
  • 優點:解決了時間回撥和生成性能問題。
  • 缺點:依賴 MySQL 數據庫。

美團的 Leaf-Snowflake 算法。

  • 雙緩沖:當前一批的 id 使用 10%時,再訪問數據庫獲取新的一批 id 緩存起來,等上批的 id 用完后直接用。
  • 優點:

     Leaf服務可以很方便的線性擴展,性能完全能夠支撐大多數業務場景。

     ID號碼是趨勢遞增的8byte的64位數字,滿足上述數據庫存儲的主鍵要求。

     容災性高:Leaf服務內部有號段緩存,即使DB宕機,短時間內Leaf仍能正常對外提供服務。

     可以自定義max_id的大小,非常方便業務從原有的ID方式上遷移過來。

     即使DB宕機,Leaf仍能持續發號一段時間。

     偶爾的網絡抖動不會影響下個號段的更新。

  • 缺點:

     ID號碼不夠隨機,能夠泄露發號數量的信息,不太安全。

怎么選擇:一般自己的內部系統,雪花算法足夠,如果還要更加安全可靠,可以選擇百度或美團的生成唯一 ID 的方案。

四、分布式事務的坑

怎么理解事務?

  • 事務可以簡單理解為要么這件事情全部做完,要么這件事情一點都沒做,跟沒發生一樣。
  • 在分布式的世界中,存在著各個服務之間相互調用,鏈路可能很長,如果有任何一方執行出錯,則需要回滾涉及到的其他服務的相關操作。比如訂單服務下單成功,然后調用營銷中心發券接口發了一張代金券,但是微信支付扣款失敗,則需要退回發的那張券,且需要將訂單狀態改為異常訂單。

坑:如何保證分布式中的事務正確執行,是個大難題。

分布式事務的幾種主要方式

  • XA 方案(兩階段提交方案)
  • TCC 方案(try、confirm、cancel)
  • SAGA 方案
  • 可靠消息最終一致性方案
  • 最大努力通知方案

XA 方案原理

圖片

XA 方案

  • 事務管理器負責協調多個數據庫的事務,先問問各個數據庫準備好了嗎?如果準備好了,則在數據庫執行操作,如果任一數據庫沒有準備,則回滾事務。
  • 適合單體應用,不適合微服務架構。因為每個服務只能訪問自己的數據庫,不允許交叉訪問其他微服務的數據庫。

TCC 方案

  • Try 階段:對各個服務的資源做檢測以及對資源進行鎖定或者預留。
  • Confirm 階段:各個服務中執行實際的操作。
  • Cancel 階段:如果任何一個服務的業務方法執行出錯,需要將之前操作成功的步驟進行回滾。

應用場景:

  • 跟支付、交易打交道,必須保證資金正確的場景。
  • 對于一致性要求高。

缺點:

  • 但因為要寫很多補償邏輯的代碼,且不易維護,所以其他場景建議不要這么做。

Sega 方案

基本原理:

  • 業務流程中的每個步驟若有一個失敗了,則補償前面操作成功的步驟。

適用場景:

  • 業務流程長、業務流程多。
  • 參與者包含其他公司或遺留系統服務。

優勢:

  • 第一個階段提交本地事務、無鎖、高性能。
  • 參與者可異步執行、高吞吐。
  • 補償服務易于實現。

缺點:

  • 不保證事務的隔離性。

可靠消息一致性方案

圖片

可靠消息一致性方案

基本原理:

  • 利用消息中間件RocketMQ 來實現消息事務。
  • 第一步:A 系統發送一個消息到 MQ,MQ將消息狀態標記為prepared(預備狀態,半消息),該消息無法被訂閱。
  • 第二步:MQ 響應 A 系統,告訴 A 系統已經接收到消息了。
  • 第三步:A 系統執行本地事務。
  • 第四步:若 A 系統執行本地事務成功,將prepared? 消息改為commit(提交事務消息),B 系統就可以訂閱到消息了。
  • 第五步:MQ 也會定時輪詢所有prepared的消息,回調 A 系統,讓 A 系統告訴 MQ 本地事務處理得怎么樣了,是繼續等待還是回滾。
  • 第六步:A 系統檢查本地事務的執行結果。
  • 第七步:若 A 系統執行本地事務失敗,則 MQ 收到Rollback? 信號,丟棄消息。若執行本地事務成功,則 MQ 收到??Commit?? 信號。
  • B 系統收到消息后,開始執行本地事務,如果執行失敗,則自動不斷重試直到成功。或 B 系統采取回滾的方式,同時要通過其他方式通知 A 系統也進行回滾。
  • B 系統需要保證冪等性。

最大努力通知方案

基本原理:

  • 系統 A 本地事務執行完之后,發送消息到 MQ。
  • MQ 將消息持久化。
  • 系統 B 如果執行本地事務失敗,則最大努力服務會定時嘗試重新調用系統 B,盡自己最大的努力讓系統 B 重試,重試多次后,還是不行就只能放棄了。轉到開發人員去排查以及后續人工補償。

幾種方案如何選擇

  • 跟支付、交易打交道,優先 TCC。
  • 大型系統,但要求不那么嚴格,考慮 消息事務或 SAGA 方案。
  • 單體應用,建議 XA 兩階段提交就可以了。
  • 最大努力通知方案建議都加上,畢竟不可能一出問題就交給開發排查,先重試幾次看能不能成功。

寫在最后

分布式還有很多坑,這篇只是一個小小的總結,從這些坑中,我們也知道分布式有它的優勢也有它的劣勢,那到底該不該用分布式,完全取決于業務、時間、成本以及開發團隊的綜合實力。后續我會繼續分享分布式中的一些底層原理,當然也少不了分享一些避坑指南。

責任編輯:張燕妮 來源: 悟空聊架構
相關推薦

2022-12-18 20:07:55

Redis分布式

2012-11-28 10:21:38

網管

2020-02-17 16:05:17

系統演進過程時間問題

2021-03-24 08:41:38

Redis 分布式鎖序列化

2021-12-14 08:19:59

系統分布式網絡

2021-12-15 07:24:56

分布式系統時鐘

2023-05-12 08:23:03

分布式系統網絡

2022-11-25 14:55:43

JavaScriptweb應用程序

2023-06-18 12:21:42

分布式系統模式架構設計

2023-02-11 00:04:17

分布式系統安全

2023-05-29 14:07:00

Zuul網關系統

2023-01-06 16:42:28

2012-11-23 10:30:28

Responsive響應式Web

2017-10-27 08:40:44

分布式存儲剪枝系統

2023-10-26 18:10:43

分布式并行技術系統

2014-11-14 15:34:11

2023-10-04 00:03:00

SQL數據庫

2019-07-17 22:23:01

分布式系統負載均衡架構

2017-12-05 09:43:42

分布式系統核心

2023-04-26 08:01:09

分布式編譯系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩国产一区二区三区 | 波多野结衣中文视频 | 久久综合伊人 | 精品视频成人 | av黄色免费 | 亚洲精彩免费视频 | 日韩精品极品视频在线观看免费 | 国产亚洲精品美女久久久久久久久久 | 亚洲精品久久久久久一区二区 | 婷婷色国产偷v国产偷v小说 | 国产亚洲精品久久午夜玫瑰园 | 国产欧美日韩精品在线观看 | 亚洲一区二区高清 | 91九色在线观看 | 久草资源在线视频 | 毛片网站在线观看视频 | www.日本精品| 黑人成人网| av一区二区三区在线观看 | 国产区精品| 成人在线视频免费观看 | 亚洲精品一区二区网址 | www.一级片 | 女人夜夜春 | 国产专区免费 | 国产免费一区 | 91美女在线观看 | 久久精品91 | 日韩一级免费观看 | 国产乱码精品一区二区三区中文 | 美女福利视频网站 | 欧美第一页 | 五月激情综合网 | 麻豆精品久久久 | 午夜影院毛片 | 日韩三区在线观看 | 黄色片在线观看网址 | 国产一区二区在线播放视频 | 亚洲人人| 国产精品国产三级国产a | 日本淫视频 |