從容器開始的良好做法

 

我真的很討厭最佳實踐這句話,主要是因爲它使人們相信只有一種正確的做事方法。但是我想圍繞一些想法來發表文章,以加強您的微服務架構。

正如我之前討論的那樣,微服務架構的實現更爲複雜,但對您的解決方案卻有很多巨大的好處。其中一些好處是:

  • 可獨立部署的部分,不再進行大規模部署
  • 更集中的測試工作
  • 爲您的解決方案的每一部分使用正確的技術
  • 我從基於集羣的部署中提高了彈性

但是對於包括我自己在內的許多人來說,此過程中最困難的部分是如何構建微服務?每部分應該多小?他們如何一起工作?

因此,如果您開始在解決方案中利用這一點,那麼我發現了一些有用的實踐。

一個服務=一個工作

第一個問題是我的容器應該多小。有什麼是太小的嗎?重點關注的一個好的經驗法則是分離問題的想法。如果您將每個用例都分解成一個單一的用途,您會發現您很快就會得到一個好的微服務設計。

讓我們看一些例子。我最近與我的一位同事一起研究了一種解決方案,最終從API中提取了信息,然後提取該信息以將其放入數據模型中。

用整體的思維方式,應該是1API調用。傳遞數據,然後循環進行處理。但是問題是吞吐量,如果我要提取67個不同的區域,並且每個區域提取300多個記錄並將其作爲批處理,那將是一個巨大的API調用的混亂。

因此,相反的,我們有一個循環遍歷區域的函數,然後將它們全部拉到blob存儲中的json文件中,然後將消息排隊。

然後我們有了另一個功能,當一條消息排隊時,它將接收該消息,讀入該區域的記錄,然後將它們保存到數據庫中。此單獨的功能是另一個微服務。

現在,這種方法有很多好處,但是最主要的是,第二個功能可以獨立於第一個功能擴展,而且我可以使用異步處理對排隊的消息進行響應。

三個詞……領域驅動設計

有關領域驅動設計的詳細定義,請參見此處。這個想法很簡單,構建軟件和應用程序的結構應該反映正在實現的業務邏輯。

因此,例如,您的微服務應反映其嘗試執行的操作。就像讓我們以最直接的示例爲例……電子商務。

如果我們必須跟蹤訂單並提交以下訂單的流程,請執行以下操作:

  • 訂單已提交。
  • 庫存已驗證。
  • 訂單付款已處理。
  • 通知已發送給供應商進行處理。
  • 確認已發送給客戶。
  • 訂單已完成併發貨。

綜上所述,實現此目標的一種方法是執行以下操作:

  • OrderService:從頭到尾管理訂單。
  • OrderRecorderService:在跟蹤系統中記錄訂單,因此您可以在整個過程中跟蹤訂單。
  • OrderInventoryService:獲取訂單內容並對照庫存進行檢查。
  • OrderPaymentService:處理訂單的付款。
  • OrderSupplierNotificationService:與第三方API交互,將訂單提交給供應商。
  • OrderConfirmationService:發送電子郵件以確認訂單已收到並正在處理。
  • OrderStatusService:繼續檢查第三方API的訂單的狀態。

如果您在上面注意到,那麼在業務流程之外,它們與業務步驟完全匹配。這提供了一種簡化的方法,使更改變得容易,並且對於新團隊成員而言也很容易理解。服務之間的通信很可能是通過隊列完成的。

例如,假設上述公司希望擴展以接受Venmo作爲付款方式。確實,這意味着您必須更新OrderPaymentServices才能接受該選項並處理付款。此外,OrderPaymentService它本身可能是不同的微服務之間的編排服務,一種按付款的方式。

使它們獨立部署

這是一個很大的問題,如果您真的想看到微服務的好處,那麼它們必須是可獨立部署的。這意味着,如果我們看一下上面的示例,我可以部署這些單獨的服務中的每個服務,並對它們進行更改,而不必進行完整的應用程序部署。

以上述情況爲例,如果我想添加新的付款方式,則應該能夠更新OrderPaymentService,簽入這些更改,然後通過生產將其部署到開發中,而不必部署整個應用程序。

現在,我第一次聽到這個消息,我以爲那是我聽過的最荒謬的事情,但是您可以做一些事情來實現這一點。

  • 每個服務應具有自己的數據存儲:如果確保每個服務都具有自己的數據存儲,則可以更輕鬆地管理版本更改。即使您要利用SQL Server之類的東西,也要確保每個微服務所利用的表都被該服務使用,並且僅被該服務使用。這可以使用模式來完成。
  • 在服務通信之間放置抽象層:例如,一個很常見的例子是排隊或事件。如果您正在傳遞消息,則只要消息離開沒有變化,就無需更新接收方。
  • 如果要直接進行API通信,請使用版本控制。如果您必須具有連接這些服務的API,則可以利用版本控制來部署和更改微服務,而不會破壞應用程序的其他部分。

頭腦靈活應變

如果您對微服務採用這種方法,那麼您很快就會注意到的最大事情之一就是每個微服務都變成了自己的黑匣子。因此,我發現在構想這些組件時最好考慮彈性。利用Polly進行重試或斷路器模式之類的事情。這些是確保您的服務保持彈性的好方法,並且會對您的應用程序產生累積影響。

例如,以我們上面的OrderPaymentService內容爲基礎,我們知道隊列消息應該與訂單和付款詳細信息一起傳入。我們可以使用顯微鏡進行這項服務,然後說,它怎麼會失敗,不難找到這樣的列表:

  • 郵件以錯誤的格式通過。
  • 無法達到付款服務。
  • 付款被拒(由於多種原因之一)。
  • 等待付款處理時服務失敗。

現在,對於上面的某些內容,這只是一些簡單的錯誤處理,例如,檢查消息的格式。我們還可以構建邏輯來檢查支付服務是否可用,並進行指數重試直到可用。

我們可能還會考慮實現斷路器,即如果嘗試了這麼多次後仍無法處理付款,則服務會切換到不良狀態並導致通知工作流程。

在最後一個場景中,我們可以實現一個狀態存儲,該狀態存儲指示正在處理的支付的狀態,當一個服務失敗並需要由另一個服務拾取時。

考慮儘早監控

這是每個人都忘記的事情,但是與前一個很好地吻合。跟蹤和監視微服務狀態的機制很重要。我經常說服務正在運行,這很正常很容易。這就像說只是導致首頁加載而已,一個完整的Web應用程序正在運行。

您應該在微服務中內置跟蹤其運行狀況的能力,併爲操作工具提供一種這樣做的方法。讓我們面對現實,最終,所有代碼最終都將被部署,並且所有部署的代碼都必須受到監控。

舉個例子,看看上面。如果我將斷路器模式構建到OrderPaymentService中,則每個故障都會更新存儲在服務內存中的狀態,該狀態說這是不健康的。然後,我可以公開一個HTTP端點,該端點返回該斷路器的狀態。

  • 關閉:服務運行良好且健康。
  • 半開:服務遇到一些錯誤,但仍在處理中。
  • 開放:由於服務不健康,該服務已脫機。

然後,我可以建立邏輯,使其變爲半開,甚至打開特定事件。

從小處着手,不要濫用Ocean

鑑於上述情況,這似乎有點諷刺。但是,如果您正在使用現有的應用程序,你永遠無法說服管理層允許你拋棄它,重新開始。因此,我過去所做的就是創建一個應用程序,當您發現有時間對應用程序的那部分進行更改時,請趁機進行重新架構並使其更具彈性。分解各個部分,並實現微服務響應以解決問題。

無狀態超過有狀態

老實說,這只是習慣的好習慣,大多數容器技術(例如DockerKubernetes或其他選項)確實贊成彈性擴展的思想以及隨時啓動或終止進程的能力。如果您必須管理容器中的狀態,這將變得更加困難。如果必須管理狀態,我絕對建議您使用外部存儲來獲取信息。

現在我知道並不是每一個都適合您的情況,但是我發現這10個項目使您更容易過渡到爲您的解決方案創建微服務,並看到這樣做的好處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章