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