我在開發人員面試中向 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)
結論
嘗試使用消息代理版本,並儘可能少地限制已定義消息(作為協議)的數量,如果系統可能變得過於復雜(流經的消息太多)並且難以控製或測試,回到編排 版本設計。
最後的
當我問這個問題時,我並不指望任何候選人能回答以上所有問題。 但我確實期待一些思考過程,至少看到“回滾鏈”問題,然後提出來討論。
在此處分享所有詳細信息,以防任何內容對您有用。
同樣,當你被問到同樣的問題時,不要回答“手動回滾”。 🙂
快樂學習!
最後的
謝謝閱讀。 希望對你下次面試有幫助。
