Java程式設計師須知 分布式微服務為什麼很難?

2021-09-12 18:02:49 字數 3099 閱讀 8309

現在,我們不斷地讚美雲原生cloud native架構(容器化和微服務),然而現實是大多數公司仍然執行單體系統。為什麼?這不是因為我們非常不時尚,而是因為分布式是非常困難的。儘管如此,它仍然是建立超大規模的、真正彈性的和快速響應的系統的唯一途徑,因此我們必須圍繞它進行整合。

在這篇文章中,我們將介紹分布式系統中一些障礙以及人們應對方法。

忘記康威定律(conway』s law),分布式系統遵循的是墨菲定律:「任何可能出錯的地方都會出錯。

在分布式系統的大規模上看,統計不是你的朋友(事後諸葛亮)。你所擁有的任何伺服器例項越多,其中乙個或多個當機的可能性就越高。而且極可能在同一時間。

在你收到警報郵件之前,伺服器已經當機,網路將會丟失資料報,磁碟將失敗,虛擬機器將意外終止。

有一些在單體架構中的保證在分布式系統中就不再會得到保障。元件(現在的服務)不再以可**的順序啟動和停止。服務可能意外重新啟動,更改其資料庫狀態或版本。結果是,沒有服務可以對另乙個服務進行假設 - 系統不依賴於1對1的通訊。

許多從故障中恢復的傳統機制可能會使分布式環境惡化。強力重試可能會使您的網路被洪水般資料報淹沒,備份恢復也並不簡單。過去解決所有這些問題的設計模式,都需要重新思考和測試。

如果沒有錯誤,分布式系統會很容易。樂觀主義會造成對安全的錯覺。分布式系統的設計必須具有彈性,能夠容納接受所有可能的發生錯誤,而不影響日常業務。

在不可靠(即分布式)系統中,傳統應用程式訊息傳遞有兩種高階方法:

不可靠但快速:將多個複製副本傳送給潛在的多個接受人,並允許訊息丟失和重複。

我們可以通過在每個服務之間放置有狀態的佇列來使此設定應用程式級別可靠,以儲存每個訊息,直至其完全處理(banq注:引入訊息佇列)。這樣做的不足之處在於它會慢一點,但是我們可能很樂意與之相處,因為如果它使生活更簡單,特別是如果我們使用可管理的有狀態的佇列服務時,那麼我們就不必擔心規模和彈性問題。

乙個可靠的方法卻不能保證快速的傳遞,但它確保所有的訊息將最終至少一次傳遞。在每個訊息至關重要且不能容忍丟失(例如信用卡交易)的環境中,這是乙個很好的方法。aws簡單佇列服務(amazon的託管佇列服務)是以可靠方式使用狀態服務的乙個例子。(banq注: apache kafka提供類似正好一次的有效一次傳遞也是適用類似信用卡之類的交易)

第二種情況是,使用不可靠的方法可以實現端對端通訊得更快(比如rpc同步方式),但這意味著服務通常不得不期待重複和無序訊息,並且一些訊息將丟失。當訊息是時間敏感的(即,如果他們不迅速採取行動,就不值得採取行動)或稍後的資料只是覆蓋早期的資料,這種情況下可能會使用不可靠的通訊。對於非常大規模的分布式系統,可以使用不可靠的訊息傳遞,因為它的開銷小且要快得多。然而,微服務設計卻需要處理應對訊息的丟失和重複。

在上述每種情況方法中,存在許多變數(例如,***和不保證的順序性),所有這些變數需要在速度、複雜性和故障率方面進行不同的權衡。

一些系統可以同時使用上述多種方法,這取決於正在傳送的訊息的型別甚至系統上的當前負載。如果您有很多行為不同的服務,就很難正確恰當使用這些方法。需要在其api中明確定義服務的行為。為您的系統中的服務進行約束或推薦的通訊行為的定義通常是有意義的,以獲得一定程度的一致性。

基本上,在分布式系統中,每台機器都有自己的時鐘,整個系統沒有乙個正確的時間。機器時鐘可能會進行同步,但是即使在同步時傳輸時間也會不同,物理時鐘也會以不同的速率執行,所以一切都會立即失去同步。

在單個機器上,乙個時鐘可以為所有執行緒和程序提供通用的時間。在分布式系統中,這在物理上都不可行。

在我們的新世界中,時鐘時代不再提供無可置疑的順序定義。在微服務世界中並不存在「什麼時候」的單一概念,所以,我們的設計不應該依賴於服務間訊息。

在分布式系統中,沒有全域性共享記憶體,因此沒有單一版本的真相。資料將分散在不同物理機器上。此外,任何指定的資料在機器之間更可能處於相對較慢和無法訪問的傳輸中,而不像在單體架構下的情況。因此,真正運**況需要基於當前的當地的資訊。

這意味著系統的不同部分的運**況並不總是一致的。在理論上,它們最終應該在整個系統中傳播訊息時變得一致,但是如果資料不斷變化,我們可能永遠不會達到完全一致的狀態,除非關閉所有新的輸入和等待。因此,服務必須處理這樣乙個事實,即他們相互呼叫時可能會因為自己的問題而獲得「舊」的或者不一致的資訊。

在乙個單體的應用程式中,大多數重要的通訊發生在乙個元件和另乙個元件之間的單個程序中。流程內部的通訊非常快,所以很多內部訊息的傳遞不是問題。但是,一旦將單體元件拆分成單獨的服務,通常會在不同的機器上執行,那麼事情變得越來越複雜。

假設你知道如下背景知識:

在最好的情況下,將訊息從一台機器傳送到另一台機器比將內部從乙個元件傳遞到另乙個元件時要花費大約100倍的時間。

許多服務使用基於文字的restful訊息進行通訊。restful訊息是跨平台的,易於使用,讀取和除錯,但傳輸速度慢。相比之下,與二進位制訊息協議配對的遠端過程呼叫(rpc)訊息不是人類可讀的,因此更難除錯和使用,但傳輸和接收速度要快得多。通過rpc方式傳送訊息的速度快20倍,比如grpc相對restful而言。

在分布式環境中的結果卻是

你應該傳送更少的訊息。您可以選擇在分布式微伺服器之間傳送的訊息數量少於在單件中的元件之間傳送的訊息量,因為每個訊息都會引入延遲(即延遲)。

考慮更有效地傳送訊息。對於您傳送的內容,您可以通過使用rpc而不是rest來傳輸訊息來幫助您的系統執行得更快。或者甚至就使用udp並手工自己處理不可靠性。(banq注:rpcc通訊屬於通訊快但不可靠型別)

如果您的系統可以次秒級(時間上短於1秒)速度更改,這是動態管理的分布式架構的目標,那麼您需要以這種速度了解問題。許多傳統的日誌工具並不是為了跟蹤這種情況而設計的。你需要確保能使用它們。

建立分布式、可擴充套件的、有彈性的系統是非常困難的,特別是對於有狀態的服務(服務需要寫資料庫儲存變動的資料)。現在是決定是否需要它的時候了。你的客戶需求是否可以容忍慢一點響應還是小型規模系統?這樣,您可以先設計乙個更小、更慢、更簡單的系統,並在構建專業知識同時逐步增加更多的複雜性。

像aws,google和azure這樣的雲計算提供商也正在開發和推出這些大部分功能,特別是彈性狀態(託管的訊息佇列和資料庫)。這些服務似乎是昂貴的,但構建和維護複雜自己的分布式服務也是昂貴的。

任何雖然可能限制您但是會處理這些複雜性的框架(如linkerd或istio或azure的服務架構)是非常值得考慮的。

關鍵的挑戰是不要低估建立正確的彈性和高度可擴充套件的服務的難度。如果決定你真的需要它,那麼全面教育大家,引入有用的約束,逐漸做好一切,並期待挫折和成功。

php分布式微服務開發 分布式微服務架構

隨著業務的不斷發展,使用者體量的快速擴張.從單體 垂直架構轉移到分布式 微服務架構是自然而然的選擇.分布式理論是分布式系統的基礎,在任何情況下分布式系統都要滿足網路分割槽容錯性,因此分布式系統都是在可用性和一致性方面做平衡.cap理論指的是在乙個分布式系統中,一致性 可用性 分割槽容錯性 在任何情況...

分布式 微服務面試

分布式 微服務面試 為什麼要拆分成多個微服務?微服務架構與傳統架構的優缺點?我們為什麼要使用分布式?分布式事物問題出現場景?如何解決分布式事物的問題?tcc是什麼?實現原理是怎麼樣的?2pc,3pc的概念是什麼?實現原理是怎樣的?訊息的最終一致性是什麼意思?如何實現訊息的最終一致性?訊息的最大努力通...

什麼是分布式 微服務

單體 傳統web專案 比較適合小專案,優點是 它的缺點也非常明顯,特別對於網際網路公司來說 通俗點說就是對於網際網路專案,屬於一直運營中有客戶一直在使用。單體應用的缺陷就暴露出來了,比如可能會因為乙個小問題,需要緊急上線,而導致整個 需要停止,這樣的情況對客戶 業務都是影響很大的,重新部署 備份對於...