請放棄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框架
- Python的函數語言程式設計,從入門到⎡放棄⎦Python函數程式設計
- 構建安全可靠的分散式儲存Oracle網路分散式Oracle
- 分散式訓練從入門到放棄分散式
- 程式設計師相信的關於時間方面的謊言程式設計師
- 分散式系統理論 - 從放棄到入門分散式
- 函式響應式程式設計(FRP)從入門到”放棄”——基礎概念篇函式程式設計FRP
- Eth:全球最大的可程式設計分散式超級計算機網路(附下載)程式設計分散式計算機網路
- 分散式系統程式設計分散式程式設計
- Circuit: Go語言編寫的最小分散式程式設計式的作業系統UIGo分散式程式設計作業系統
- 程式設計師的生活充滿壓力,但你不能放棄!程式設計師
- 設計模式從放棄到入門設計模式
- 21世紀程式設計師最大的謊言:學歷及讀書無用論!程式設計師
- 拆穿安全Web瀏覽的十大謊言,網際網路營銷Web
- [從RPC到Go-Micro 壹]Go語言實現RPC程式設計RPCGoC程式程式設計
- 多個網路請求的介面設計
- C語言Socket程式設計(計算機網路作業)C語言程式設計計算機網路
- 程式設計師快放棄 Android 9.0 吧,10.0 正在來的路上!程式設計師Android
- 入門到放棄node系列之網路模組(二)
- 程式設計師最常見的謊話,太準了程式設計師
- 函數語言程式設計-鏈式程式設計RAC函數程式設計
- 基於CORBA的分散式程式設計(五) (轉)ORB分散式程式設計
- 基於CORBA的分散式程式設計(九) (轉)ORB分散式程式設計
- 基於CORBA的分散式程式設計(十一) (轉)ORB分散式程式設計
- 基於CORBA的分散式程式設計(七) (轉)ORB分散式程式設計
- 基於CORBA的分散式程式設計(十) (轉)ORB分散式程式設計
- RPC設計應該使用哪種網路IO模型?RPC模型
- 放棄的智慧
- 《Java 8函數語言程式設計》選讀:第一個Lambda表示式Java函數程式設計
- 衛報:放棄社交網路後的英國年輕人獲得更多快樂
- USA Network:55%的美國年輕人稱願意放棄社交網路
- iOS鏈式程式設計及函數語言程式設計iOS程式設計函數
- NodeJs 入門到放棄 — 網路伺服器(三)NodeJS伺服器
- 開發寶典:基於分散式物件的網遊程式結構設計分散式物件
- 分散式佇列程式設計優化篇分散式佇列程式設計優化