請放棄RPC!分散式程式設計第一謊言:網路是可靠的 - David Boike
與幾十年前相比,網路相當可靠,隨著我們繼續構建更大,更全球分佈的系統,我們使自己容易受到可能發生的所有不良事件的影響。
為了解決這個問題,我們將不得不放棄同步請求/響應型別程式設計。呼叫方法(稱為遠端過程呼叫或RPC)的物件導向模型傾向於分解為網路不可靠時的條件,將我們的系統置於非確定性狀態,這是非常難以擺脫的狀態。
現象
請看兩個事故:
我們上網的ISP有兩個路由器:主路由器和備用路由器。如果有一天,主路由器出現故障。需要切換到備份,卻發現其路由表在很長一段時間內沒有更新,這導致大部分人無法上網。
另一種情況:專案使用Oracle資料庫。一切在開發環境中都很有效,但在生產中還有一個額外的負載均衡器和防火牆。每隔一段時間,負載均衡器就會默默地將連線到資料庫的TCP丟棄,但是這些錯誤的連線繼續位於連線池中,因此下次需要連線時,就會得到一個意外拋錯。
就在最近,6月12日,亞洲的一家網際網路服務提供商在全球大部分地區打破了網際網路,在歐洲引發了網際網路問題。還有twitter Facebook google等同時出現大面積斷網。
一般而言,無論是本地還是全球,您都不能信任任何網路。硬體,軟體和安全性都可能導致問題。這在分散式計算的第一個謬論中被編纂:網路是可靠的。
這對於HTTP通訊或任何請求/響應或遠端過程呼叫(RPC)通訊型別尤其成問題。
解決方案
要提供真正可靠的系統,您必須接受並非總是可以進行跨網路通訊。因為我們無法保證通訊嘗試能夠成功,所以我們需要提供一種在故障後自動重試的工具。為了防止在重試期間出現故障,我們可以使用名為store and forward的模式。我們可以將資料儲存在本地儲存中,而不是直接將資料傳送到遠端伺服器。這樣,當我們再次啟動時,我們就準備好繼續我們離開的地方。我們可以使用事務來確保我們繼續重試,直到處理成功。
這超出了圍繞Web服務呼叫的簡單重試迴圈的級別,如果伺服器在崩潰時執行,則會失敗。我們需要額外的基礎設施來實現這些保障
非同步訊息傳遞
有許多不同的技術,稱為可靠訊息傳遞或訊息排隊系統,可以解決這些型別的問題。在Microsoft平臺上,最著名的是Microsoft訊息佇列(MSMQ),在Azure上,有Azure Queue Storage和Azure Service Bus。在Microsoft生態系統之外,有RabbitMQ,ActiveMQ和ZeroMQ。基本上任何帶有“MQ”的東西都表明該產品符合這一系列技術。
這些排隊技術將諸如Web服務呼叫之類的東西包含在稱為訊息的孤立的,離散的工作單元中。訊息佇列使用儲存和轉發來確保訊息到達它需要的位置。它可以促進自動重試,因為即使在系統崩潰之後也可以反覆嘗試訊息處理。有些甚至支援事務,因此只有在業務事務成功時才會完全使用訊息。這樣,可以保證每個訊息只成功處理一次。
與簡單的重試迴圈相比,排隊技術具有額外的優勢。例如,如果我們試圖建立一個客戶並收到HTTP超時,我們將無法知道伺服器是否收到了資料並且根本無法響應,或者是否相反,資料根本沒有到達。
重試帶來了伺服器端複製的可能性。如果我們重新嘗試建立客戶,我們可能會意外地建立客戶兩次。
訊息佇列帶有訊息ID的概念,以便伺服器可以決定嘗試是否是重試。實質上,訊息傳遞允許在伺服器端進行重複資料刪除。
放棄請求/響應
非同步訊息傳遞需要稍微改變思路,因為它不能提供執行典型Web服務呼叫中看到的傳統請求/響應的能力。
將訊息傳送到訊息佇列是一種即發即棄的操作。您將訊息放入佇列中,最終它將進入伺服器,伺服器將處理它。您沒有在下一行程式碼上獲得立即返回值。
最終,透過解決某些基礎架構問題,非同步訊息傳遞會迫使您重新設計系統的邏輯流程。
這是排隊技術的艱難飛躍:並不是說他們有一個難以使用的API(他們沒有),但他們需要放棄更傳統的請求/響應程式設計模型。
不幸的是,你不能只使用HTTP系統,插入佇列並運送它。它需要對系統進行重大的重新設計,有時需要重寫。
這可能很嚇人,但結果是值得的。
(banq注:這也是CAP定理的由來,CAP是分散式系統黃金定律,沒有人能夠逃脫其三選二,CAP其中有一個P分割槽容錯,就是針對分散式網路的不可靠造成腦裂分割槽的容忍度,如果你需要P,那麼只能C和A之間選擇,但是普通人只會忽視P,選擇CA,這也是關聯式資料庫的特點,當人們處於一個世界舒適久了,忘記更大的世界,)
相關文章
- 設計一個分散式RPC框架分散式RPC框架
- RPC框架的可靠性設計RPC框架
- 構建安全可靠的分散式儲存Oracle網路分散式Oracle
- 程式設計師相信的關於時間方面的謊言程式設計師
- 分散式訓練從入門到放棄分散式
- Eth:全球最大的可程式設計分散式超級計算機網路(附下載)程式設計分散式計算機網路
- [從RPC到Go-Micro 壹]Go語言實現RPC程式設計RPCGoC程式程式設計
- 分散式系統程式設計分散式程式設計
- 程式設計師快放棄 Android 9.0 吧,10.0 正在來的路上!程式設計師Android
- 拆穿安全Web瀏覽的十大謊言,網際網路營銷Web
- 21世紀程式設計師最大的謊言:學歷及讀書無用論!程式設計師
- 函數語言程式設計-鏈式程式設計RAC函數程式設計
- RPC設計應該使用哪種網路IO模型?RPC模型
- NodeJs 入門到放棄 — 網路伺服器(三)NodeJS伺服器
- 再用RNN神經網路架構設計生成式語言模型RNN神經網路架構模型
- [原始碼解析] PyTorch 分散式(18) --- 使用 RPC 的分散式管道並行原始碼PyTorch分散式RPC並行
- Scala 函數語言程式設計(一) 什麼是函數語言程式設計?函數程式設計
- Java 網路程式設計 —— 非阻塞式程式設計Java程式設計
- 入門到放棄node系列之網路模組(二)
- 併發程式設計從入門到放棄系列開始和結束程式設計
- 網路通訊程式設計程式設計
- py網路工具程式設計程式設計
- 體驗go語言的風騷式程式設計Go程式設計
- 防禦式程式設計之斷言assert的使用程式設計
- Go語言的context包從放棄到入門GoContext
- JavaScript函數語言程式設計之pointfree與宣告式程式設計JavaScript函數程式設計
- 瞭解 JavaScript 函數語言程式設計 -- 什麼是純函式JavaScript函數程式設計函式
- Allen Holub: 敏捷已經腐化到是IT中最大的謊言!敏捷
- 函數語言程式設計:Lambda 表示式函數程式設計
- 【譯】需要學習的是程式設計,而不是程式語言程式設計
- python 網路篇(網路程式設計)Python程式設計
- python是函數語言程式設計嗎Python函數程式設計
- 函數語言程式設計 vs 物件導向程式設計 vs 程式式程式設計的JS演示比較 - DEV函數程式設計物件JSdev
- 同樣是學程式設計,別人成功轉行Python,你卻失敗選擇放棄,問題在哪?程式設計Python
- 程式設計師到底是幹什麼的?請不要再黑程式設計師了程式設計師
- 簡單是 Python 程式設計的第一要則Python程式設計
- 請問你知道分散式系統設計模式的最低水位線思想麼?分散式設計模式
- 請問你知道分散式系統設計模式的分割日誌思想麼?分散式設計模式