avatar胡家維 Hu Kenneth

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

1863

Abstract

庫、文件等)</li><li>協調器是瓶頸和SPF(單點故障)</li></ul><p id="1f2f">由於以上。 用例非常限於:</p><ul><li>跨多個數據庫提交</li><li>簡單快捷的服務。 並且大部分情況都有望成功(重試是有代價的,佔用一個連接,再次阻塞請求)</li><li>可用於同步進程,不關心性能。</li></ul><h2 id="0d7e">改進版本 — — 三階段提交</h2><p id="509f">所以相比2pc,3pc多了一個步驟:can commit, pre-commit, commit</p><figure id="ac30"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*eqAFoKf1_MqV3LfJ"><figcaption></figcaption></figure><p id="c361">優點</p><ul><li>如果“可以提交”調用失敗,甚至不必執行任何操作。</li><li>將一個提交調用分成 2 個較小的邏輯部分,一個專注於預檢查(健康檢查,如 ping),另一個專注於業務邏輯。</li><li>因為在上面,交易成功的機會應該更高</li></ul><p id="6f6b">缺點</p><ul><li>鎖定時間更長</li><li>仍然是一個阻塞過程</li><li>仍然。 協調員失敗意味著一切都無法正常工作。 (它必須是一個帶有恢復過程的集群)</li></ul><h1 id="b290">TCC — 嘗試-確認-取消</h1><figure id="10ae"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*3NGeifbV9kX-ErrH"><figcaption></figcaption></figure><p id="e56d">正如你在上面看到的,</p><p id="a606">第一件事是每個服務都需要實現這個契約:調用者有 3 個接口 try、confirm 和 cancel。</p><p id="871b">然後是圖片中的2個角色。</p><ul><li>應用。 這是商業應用程序。 調用 try() 服務嘗試進行交易(預檢查、準備資源等)</li><li>交易經理。 跟踪發生的交易並存儲日誌。 然後根據服務調用進行回滾或提交。 它與不同的服務對話,並為業務應用程序提供一個包裝器來確認或取消。</li></ul><p id="961f">它看起來更好。</p><p id="70f7">但是有一個限制,服務調用必須是冪等的,意思是:</p><ul><li>相同的輸入,相同的輸出</li><li>不管叫多少次</li></ul><p id="7968">為什麼? 支持重試提交或取消,多次提交或取消時,對系統狀態無副作用。</p><p id="6a0a">優點</p><ul><li>減少鎖定(與 2 件或 3 件相比)。</li><li>支持重試(因為冪等性)</li></ul><p id="089f">缺點</p><ul><li>每個服務都必須提供嘗試、確認和取消服務。 這可能對所有服務都沒有意義</li></ul><h1 id="7e4e">傳奇模式</h1><p id="0c25">傳奇只是一個名字。 它是分佈式系統中用於確保事務的一種模式。</p><p id="64a7">2pc 或 3pc 的問題很明顯。 阻塞和鎖定。 這導致緩慢和低吞吐量。</p><p id="fe63">Tcc 可能適用於某些用例,但並非全部。 (強制嘗試、確認、取消實施限制了用例)</p><p id="faf3">我們需要其他東西來處理更多用例。</p><p id="3b44">我們先從簡單的開始,以ecoms進程為例。</p><figure id="09fc"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*pT5VDCQE-FtvqX9i"><figcaption></figcaption></figure><p id="0224">所以當異常發生時,我們要確保一切都正確回滾。 意思是,使以下發生:</p><figure id="2917"><img

Options

src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*9zWhIriocxwpZuWk"><figcaption></figcaption></figure><p id="cf57">Saga模式就是為了解決這個問題而來的。</p><p id="cb4d">怎麼運行的</p><figure id="d360"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*fMU82mmEox14pRGh"><figcaption></figcaption></figure><p id="f11b">以上是 saga 模式的<b>編排</b>版本。</p><p id="b7e4">這個想法很簡單。</p><p id="fd8d">在中間放置一個“服務包裝器”(或稱為協調器或編排器)。 與每個服務提供商交談並確保回滾調用正確發生。</p><p id="98ff">日益增加的複雜性可能會使這個服務包裝器成為瓶頸(在復雜性或性能方面)。</p><p id="c8cd">所以,需要確保這個中間服務:</p><ul><li>把事情簡單化</li><li>定期進行性能基準測試</li><li>高可用性</li><li>準備恢復機制</li></ul><p id="e262">優點</p><ul><li>簡單易懂</li><li>易於測試(與 Choreography 版本相比)</li><li>沒有無限循環</li></ul><p id="5489">缺點</p><ul><li>服務包裝器可能會變得複雜並成為瓶頸或單點故障</li></ul><p id="7bab">Saga 還有另一個版本,稱為 <b>Choreography</b></p><p id="3f05">讓我們快速瀏覽一下。</p><figure id="87b9"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*06elP0aYNeHGOcG4"><figcaption></figcaption></figure><p id="45e1">實現是非常不同的。</p><p id="b99e">每個服務都綁定到消息代理,而不是在中間有一個“saga 服務包裝器”(或協調器),它們自己負責回滾。</p><p id="369b">所以,</p><ul><li>一切都取決於消息隊列</li><li>所有動作都由消息驅動(與舊事件驅動的想法相同)</li><li>所有進程都是異步的</li><li>每個服務都是訂閱者也是消息發送者</li></ul><p id="3bf2">優點</p><ul><li>無需搭建中間服務</li><li>服務依賴僅在消息上</li><li>所有異步流程使系統易於擴展(就業務而言)</li><li>負載主要在消息代理上(可以通過已知的解決方案進行縮放,例如 rabbitMQ 或 Kafka),而不是轉向 App 服務器(繁瑣且工作量更大)</li></ul><p id="1717">缺點</p><ul><li>難以理解</li><li>難以測試</li><li>有可能出現無限循環(例如 serviceA 監聽 messageB,serviceB 監聽 messageA)</li></ul><h2 id="3935">結論</h2><p id="7f7e">嘗試使用消息代理版本,並儘可能少地限制已定義消息(作為協議)的數量,如果系統可能變得過於復雜(流經的消息太多)並且難以控製或測試,回到編排 版本設計。</p><h2 id="7c0f">最後的</h2><p id="5ac5">當我問這個問題時,我並不指望任何候選人能回答以上所有問題。 但我確實期待一些思考過程,至少看到“回滾鏈”問題,然後提出來討論。</p><p id="0ced">在此處分享所有詳細信息,以防任何內容對您有用。</p><p id="ac0f">同樣,當你被問到同樣的問題時,不要回答“手動回滾”。 🙂</p><p id="91c9">快樂學習!</p><h2 id="e471">最後的</h2><p id="e77b">謝謝閱讀。 希望對你下次面試有幫助。</p></article></body>

我在開發人員面試中向 3 個人問了這個系統設計問題,但他們都沒有給出答案

source : https://iorilan.medium.com/i-asked-this-system-design-question-to-3-guys-during-a-developer-interview-and-none-of-them-gave-9c23abe45687 by LORY

一個常見的系統設計問題。

問題

幾週前,一位應聘者進來了,我們開始了面試(高級開發人員,第三輪)流程。 由於他有互聯網公司工作經驗,著名的ecoms公司。

我問他的第一個問題是“你在團隊中做什麼? 告訴我你目前正在進行的項目的細節,越詳細越好”。

TBH,這是一個非常標準的問題。 我期待一個準備充分的可靠答案。

他回答說:“當然,我們的團隊正在處理支付、與支付網關的集成以及與銀行同步發票。 由於我們的架構是微服務,我們的團隊正在研究支付服務。 為其他團隊提供支付服務”。

好的。

然後我問“由於您的系統正在處理支付網關,您是否遇到過任何問題? 就像付款在網關中通過但在您這邊失敗了? 還是在銀行發現了雙重發票?”

他回答說,“好吧,這有時會發生,當它發生時,我們手動修復它”。

“你如何手動修復”? 我又問。

“觸發一些腳本來同步數據或狀態,”他說。

“你的意思是手動回滾你身邊或網關或任何銀行的交易”?

他說是的。

我又問,“我這樣問,在分佈式系統中如何保證事務提交成功?”。

“手動修復,”他又說了一遍。

🙂

答案

如果您面試互聯網公司或處理分佈式系統的公司的任何職位。

您需要研究分佈式系統事務處理。

讓我們直接深入了解細節。

2 階段提交

思路和上面一樣簡單。

這裡協調器要確保對 seriveA 和 serviceB 的調用都沒有發生或兩者都發生。

  • 在 seriveA 和 serviceB 上提供 prepare() 接口
  • 調用兩個 prepare() 函數並獲得結果
  • 根據響應進行提交或回滾

等等,如果提交或回滾時一直失敗怎麼辦?

將狀態存儲在協調器中(或者可以緩存並設置到期日期,一段時間後將項目作廢)

缺點很明顯:

  • 這是一個阻塞過程。 非常糟糕的性能 — — 低吞吐量
  • 長時間鎖定資源(數據庫、文件等)
  • 協調器是瓶頸和SPF(單點故障)

由於以上。 用例非常限於:

  • 跨多個數據庫提交
  • 簡單快捷的服務。 並且大部分情況都有望成功(重試是有代價的,佔用一個連接,再次阻塞請求)
  • 可用於同步進程,不關心性能。

改進版本 — — 三階段提交

所以相比2pc,3pc多了一個步驟:can commit, pre-commit, commit

優點

  • 如果“可以提交”調用失敗,甚至不必執行任何操作。
  • 將一個提交調用分成 2 個較小的邏輯部分,一個專注於預檢查(健康檢查,如 ping),另一個專注於業務邏輯。
  • 因為在上面,交易成功的機會應該更高

缺點

  • 鎖定時間更長
  • 仍然是一個阻塞過程
  • 仍然。 協調員失敗意味著一切都無法正常工作。 (它必須是一個帶有恢復過程的集群)

TCC — 嘗試-確認-取消

正如你在上面看到的,

第一件事是每個服務都需要實現這個契約:調用者有 3 個接口 try、confirm 和 cancel。

然後是圖片中的2個角色。

  • 應用。 這是商業應用程序。 調用 try() 服務嘗試進行交易(預檢查、準備資源等)
  • 交易經理。 跟踪發生的交易並存儲日誌。 然後根據服務調用進行回滾或提交。 它與不同的服務對話,並為業務應用程序提供一個包裝器來確認或取消。

它看起來更好。

但是有一個限制,服務調用必須是冪等的,意思是:

  • 相同的輸入,相同的輸出
  • 不管叫多少次

為什麼? 支持重試提交或取消,多次提交或取消時,對系統狀態無副作用。

優點

  • 減少鎖定(與 2 件或 3 件相比)。
  • 支持重試(因為冪等性)

缺點

  • 每個服務都必須提供嘗試、確認和取消服務。 這可能對所有服務都沒有意義

傳奇模式

傳奇只是一個名字。 它是分佈式系統中用於確保事務的一種模式。

2pc 或 3pc 的問題很明顯。 阻塞和鎖定。 這導致緩慢和低吞吐量。

Tcc 可能適用於某些用例,但並非全部。 (強制嘗試、確認、取消實施限制了用例)

我們需要其他東西來處理更多用例。

我們先從簡單的開始,以ecoms進程為例。

所以當異常發生時,我們要確保一切都正確回滾。 意思是,使以下發生:

Saga模式就是為了解決這個問題而來的。

怎麼運行的

以上是 saga 模式的編排版本。

這個想法很簡單。

在中間放置一個“服務包裝器”(或稱為協調器或編排器)。 與每個服務提供商交談並確保回滾調用正確發生。

日益增加的複雜性可能會使這個服務包裝器成為瓶頸(在復雜性或性能方面)。

所以,需要確保這個中間服務:

  • 把事情簡單化
  • 定期進行性能基準測試
  • 高可用性
  • 準備恢復機制

優點

  • 簡單易懂
  • 易於測試(與 Choreography 版本相比)
  • 沒有無限循環

缺點

  • 服務包裝器可能會變得複雜並成為瓶頸或單點故障

Saga 還有另一個版本,稱為 Choreography

讓我們快速瀏覽一下。

實現是非常不同的。

每個服務都綁定到消息代理,而不是在中間有一個“saga 服務包裝器”(或協調器),它們自己負責回滾。

所以,

  • 一切都取決於消息隊列
  • 所有動作都由消息驅動(與舊事件驅動的想法相同)
  • 所有進程都是異步的
  • 每個服務都是訂閱者也是消息發送者

優點

  • 無需搭建中間服務
  • 服務依賴僅在消息上
  • 所有異步流程使系統易於擴展(就業務而言)
  • 負載主要在消息代理上(可以通過已知的解決方案進行縮放,例如 rabbitMQ 或 Kafka),而不是轉向 App 服務器(繁瑣且工作量更大)

缺點

  • 難以理解
  • 難以測試
  • 有可能出現無限循環(例如 serviceA 監聽 messageB,serviceB 監聽 messageA)

結論

嘗試使用消息代理版本,並儘可能少地限制已定義消息(作為協議)的數量,如果系統可能變得過於復雜(流經的消息太多)並且難以控製或測試,回到編排 版本設計。

最後的

當我問這個問題時,我並不指望任何候選人能回答以上所有問題。 但我確實期待一些思考過程,至少看到“回滾鏈”問題,然後提出來討論。

在此處分享所有詳細信息,以防任何內容對您有用。

同樣,當你被問到同樣的問題時,不要回答“手動回滾”。 🙂

快樂學習!

最後的

謝謝閱讀。 希望對你下次面試有幫助。

Interview
Software Design
Software Development
Software Architecture
Recommended from ReadMedium