微服務到底該怎么樣部署呢?
微服務應用程序可以以多種方式運行,每種方式都有不同的權衡和成本結構。適用于跨越幾個服務的小型應用程序可能不足以用于大型系統。
從簡單到復雜,以下是運行微服務的五種方式:
- 單機多進程:購買或租用服務器并將微服務作為進程運行。
- 多臺機器,多進程:顯而易見的下一步是添加更多服務器并分配負載,提供更高的可擴展性和可用性。
- 容器:將微服務封裝在容器中,可以更輕松地與其他服務一起部署和運行。這也是邁向 Kubernetes 的第一步。
- 編排器:Kubernetes 或 Nomad 等編排器是完整的平臺,旨在同時運行數千個容器。
- 無服務器:無服務器允許我們忘記進程、容器和服務器,并直接在云中運行代碼。
方案一:單機多進程
在最基本的層面上,我們可以在一臺機器上將微服務應用程序作為多個進程運行。每個服務偵聽不同的端口并通過環回接口進行通信。
微服務部署的最基本形式使用單機。應用程序是一組加上負載平衡的進程。
這種簡單的方法有一些明顯的好處:
- 輕量級:沒有開銷,因為它只是在服務器上運行的進程。
- 方便:這是體驗微服務的好方法,無需其他工具的學習曲線。
- 輕松排除故障:一切都在同一個地方,因此如果您有持續交付,那么在出現問題時發現問題或恢復到工作配置非常簡單。
- 固定計費:我們知道我們每個月必須支付多少。
DIY 方法最適合只有少量微服務的小型應用程序。除此之外,它還不夠,因為:
- 沒有可擴展性:一旦你最大化了服務器的資源,就是這樣。
- 單點故障:如果服務器宕機,應用程序也會隨之宕機。
- 脆弱的部署:我們需要自定義部署和監控腳本來確保服務安裝和運行正確。
- 無資源限制:任何微服務進程都可以消耗任意數量的 CPU 或內存,從而可能使其他服務處于饑餓狀態并使應用程序處于降級狀態。
- 此選項的持續集成(CI) 將遵循相同的模式:在 CI管道中[url=
https://semaphoreci.com/blog/build-stage]構建[/url]和測試工件,然后使用持續部署進行部署。
這是學習微服務基礎知識的最佳選擇。您可以運行一個小型微服務應用程序來熟悉。單臺服務器將帶您走很遠,直到您需要擴展,此時您可以升級到下一個選項。
方案2:多臺機器和流程
該選項本質上是選項1的升級。當應用程序超出服務器的容量時,我們可以縱向擴展(升級服務器)或橫向擴展(添加更多服務器)。在微服務的情況下,水平擴展到兩臺或多臺機器更有意義,因為我們獲得了更高的可用性作為獎勵。而且,一旦我們有了分布式設置,我們總是可以通過升級服務器來擴大規模。
負載均衡器仍然是單點故障。為了避免這種情況,多個平衡器可以并行運行。
然而,水平縮放并非沒有問題。超越一臺機器會帶來一些關鍵點,這些關鍵點會使故障排除變得更加復雜,并且會出現使用微服務架構帶來的典型問題。
- 我們如何關聯分布在許多服務器之間的日志文件?
- 我們如何收集合理的指標?
- 我們如何處理升級和停機?
- 我們如何處理流量的高峰和下降?
這些都是分布式計算固有的問題,一旦涉及多臺機器,您就會遇到(并且必須處理)問題。
如果您有幾臺備用機器并希望提高應用程序的可用性,則此選項非常有用。只要您保持簡單,使用或多或少統一的服務(相同的語言,類似的框架),您就可以了。一旦您通過了某個復雜度閾值,您將需要容器來提供更大的靈活性。
方案 3:使用容器部署微服務
雖然直接將微服務作為進程運行非常有效,但它是有代價的。
- 必須使用必要的依賴項和工具精心維護服務器。
- 一個失控的進程會消耗所有的內存或 CPU。
- 部署和監控微服務是一個脆弱的過程。
所有這些缺點都可以通過容器來緩解。容器是包含程序運行所需的一切的包。容器鏡像是一個獨立的單元,可以在任何服務器上運行,而無需先安裝任何依賴項或工具(容器運行時本身除外)。
容器提供了足夠的虛擬化來單獨運行軟件。有了它們,我們可以獲得以下好處:
- 隔離:包含的進程彼此和操作系統隔離。每個容器都有一個私有文件系統,因此不可能發生依賴沖突(只要您不濫用卷)。
- 并發性:我們可以運行同一個容器鏡像的多個實例而不會發生沖突。
- 更少的開銷:由于不需要啟動整個操作系統,容器比虛擬機輕得多。
- 免安裝部署:安裝容器只是下載和運行鏡像的問題。無需安裝步驟。
- 資源控制:我們可以對容器設置 CPU 和內存限制,這樣它們就不會破壞服務器的穩定性。
上圖容器化工作負載需要 CI/CD 上的鏡像構建階段。
1、服務器上的容器
這種方法用容器代替了流程,因為它們給了我們更大的靈活性和控制力。與選項 2 一樣,我們可以在任意數量的機器上分配負載。
將微服務進程包裝在容器中使它們更加便攜和靈活。
2、無服務器容器
到目前為止描述的所有選項都是基于服務器的。但是軟件公司不從事管理服務器的業務——必須配置、修補和升級的服務器——他們從事解決代碼問題的業務。因此,許多公司寧愿盡可能避免使用服務器也就不足為奇了。
AWS Fargate和Heroku等容器即服務產品使運行容器化應用程序成為可能,而無需處理服務器。我們只需要構建容器鏡像并將其指向云提供商,它會處理剩下的事情:配置虛擬機,下載、啟動和監控鏡像。這些托管服務通常包括一個內置的負載均衡器,這是一件少擔心的事情。
使用 Fargate 的彈性容器服務 (ECS) 讓我們無需租用服務器即可運行容器。它們由云提供商維護。
以下是托管容器服務的一些好處:
- 無服務器:無需維護或修補服務器。
- 輕松部署:只需構建一個容器鏡像并告訴服務使用它。
- 自動縮放:云提供商可以在需求激增時提供更多容量,或者在沒有流量時停止所有容器。
但是,在開始之前,您必須意識到一些重大缺點:
- 供應商鎖定:這是一個大問題。擺脫托管服務總是充滿挑戰,因為云供應商提供并控制了大部分基礎設施。
- 資源有限:托管服務強加了無法避免的 CPU 和內存限制。
- 更少的控制:我們沒有與其他選項相同的控制水平。如果您需要托管服務未提供的功能,那您就不走運了。
方案 4:編排器
編排器是專門在一組服務器上分配容器工作負載的平臺。最著名的編排器是Kubernetes,這是一個由 Google 創建的開源項目,由Cloud Native Computing Foundation維護。
除了容器管理之外,Orchestrator 還提供廣泛的網絡功能,例如路由、安全性、負載平衡和集中式日志——運行微服務應用程序可能需要的一切。
Kubernetes 使用 pod 作為調度單元。Pod 是一組共享一個網絡地址的一個或多個容器。
使用 Kubernetes,我們擺脫了自定義部署腳本。相反,我們使用清單來編碼所需的狀態,并讓集群負責其余的工作。
持續部署管道將清單發送到集群,集群會采取必要的步驟來完成它。
Kubernetes 得到所有云提供商的支持,是事實上的微服務部署平臺。因此,您可能認為這是運行微服務的絕對最佳方式。對于許多公司來說,這是事實,但也需要牢記以下幾點:
- 復雜性:編排器以其陡峭的學習曲線而聞名。如果不小心的話,射中自己的腳并不少見。對于簡單的應用程序,編排器是多余的。
- 管理負擔:維護 Kubernetes 安裝需要大量專業知識。幸運的是,每個體面的云供應商都提供了托管集群,可以省去所有的管理工作。
- 技能組合:Kubernetes 開發需要專門的技能組合。了解所有活動部件并了解如何排除部署失敗的故障可能需要數周時間。在團隊熟悉這些工具之前,過渡到 Kubernetes 可能會很慢并且會降低生產力。
方案 5:將微服務部署為無服務器函數
無服務器函數偏離了我們迄今為止討論的所有其他內容。我們使用云來簡單地按需運行代碼,而不是服務器、進程或容器。AWS Lambda和Google Cloud Functions等無服務器產品可處理可擴展和高可用性服務所需的所有基礎設施細節,讓我們可以專注于編碼。
無服務器函數可自動擴展并按使用計費。
這是一個完全不同的范式,具有不同的優點和缺點。從好的方面來說,我們得到:
- 易用性:我們可以在不編譯或構建容器映像的情況下即時部署功能,這對于嘗試和原型設計非常有用。
- 易于擴展:您(基本上)獲得了無限的可擴展性。云將提供足夠的資源來滿足需求。
- 按使用付費:您根據使用情況付費。如果沒有需求,則不收費。
- 然而,缺點可能是相當大的,使得無服務器不適合某些類型的微服務:
- 供應商鎖定:與托管容器一樣,您正在購買供應商的生態系統。從供應商那里遷移可能要求很高。
- 冷啟動:不常用的功能可能需要很長時間才能啟動。發生這種情況是因為云提供商降低了附加到未使用功能的資源。
- 資源有限:每個函數都有內存和時間限制——它們不能是長時間運行的進程。
- 有限的運行時:僅支持少數語言和框架。您可能會被迫使用您不習慣的語言。
看不見的賬單:由于成本是基于使用情況的,因此很難預測月底發票的大小。使用高峰可能會導致令人討厭的意外。
無服務器為可擴展性提供了一種無需干預的解決方案。與 Kubernetes 相比,它沒有給你太多的控制權,但它更容易使用,因為你不需要專門的 serverless 技能。對于快速發展的小公司來說,無服務器是一個很好的選擇,只要他們能夠忍受它的缺點和限制。
結論
運行微服務應用程序的最佳方式是由許多因素決定的。使用容器(或進程)的單個服務器是試驗或測試原型的絕佳起點。
如果應用程序成熟并且跨越許多服務,您將需要更健壯的東西,例如托管容器或無服務器,并且隨著應用程序的增長,可能還會需要 Kubernetes。