6-微服務部署策略

本文出自Nginx官網,是微服務介紹系列文章的第六篇。原文地址:https://www.nginx.com/blog/deploying-microservices/

1.介紹

在第一篇文章中我們比較了微服務架構應用和單體應用的差異,討論了微服務架構的優點與缺點;第二篇文章和第三篇文章討論了進程間通信相關的問題;第四篇文章討論服務發現問題;第五篇文章介紹瞭如何使用事件驅動架構處理分佈式數據管理;在本篇文章中我們討論微服務的部署策略。

2.動機

單體應用一般會部署多個副本,通常在多臺物理機或虛擬機上部署多個應用實例來實現,這比微服務應用的部署簡單多了。

微服務架構的應用由幾十甚至幾百個服務組成,服務使用的開發語言和技術框架可能各不相同,每個服務都是獨立應用,有自己獨有的部署方式、資源需求、伸縮特性和監控需求。有可能需要根據某個服務的具體需求,運行特定數量的實例;每個服務有不同的CPU、內存和IO需求;除了這些複雜性之外,更具挑戰性的需求是服務部署必須快速、可靠、低成本。下面介紹幾種不同的部署模式。

3.單主機多服務實例模式

該種模式是應用部署的傳統模式,在每個物理機或者虛擬機上使用知名端口部署多個服務實例,下圖展示了該種模式:


這種模式有很多變種,一種變種是每個服務實例是一個進程或者進程組:你可能使用Tomcat以Web應用的形式部署服務;Node.js的服務實例可能包含一個父進程、一個或者多個子進程。

另外一種變種是在一個進程內或者進程組內運行多個服務實例,比如,在一個Tomcat服務器上部署多個Web應用;在一個OSGI容器中運行多個OSGI包。

這種模式的主要好處是資源利用比較高效,多個服務實例共享服務器和操作系統;在一個進程或者進程組中運行多個服務實例資源利用會更高效,比如多個Web應用共享一個Tomcat和JVM。

另外一個優點是部署服務速度快,只用把服務拷貝到服務器上啓動即可:服務可能是Java編譯成的JAR或者WAR文件,也可能是Node.js或者Ruby的源代碼;不管哪種,需要通過網絡傳遞的數據量不大。

這種模式下,啓動速度通常比較快。如果服務本身是進程,簡單啓動即可;如果服務是容器進程或者容器進程組的實例,將實例動態部署到容器進程或者重啓容器進程即可。

這種模式的缺點是除了服務實例自身作爲進程之外,其他情況下服務實例不是相互獨立的。也許你能精確監測每個服務的資源佔用率,卻不能限制每個服務的資源使用;某個異常服務可能會消耗光主機的CPU和內存資源。

如果多個服務運行在同一個進程中,那服務就沒有一點兒獨立性了。所有的服務實例共享JVM堆棧,某個異常服務會影響同進程中的其他服務;更嚴重的是,你根本沒有辦法監測每個服務實例的資源佔用。

另外一個問題是部署人員需要了解更多細節,不同服務可能使用不同的語言和框架,這意味着開發團隊需要跟部署團隊共享很多細節,這增加了部署工作的複雜度,給部署工作帶來了風險。

4.單主機單服務實例模式

在這種模式下,服務實例獨立運行在它自己的主機上,有兩種形式:單虛擬機單服務實例和單容器單服務實例。

單虛擬機單服務實例

該種模式下,將服務打包成虛擬機映像文件,如Amazon EC2 AMI;每個服務實例都是一個虛機,如下圖所示:


Netflix使用這種方式部署視頻流服務,它使用Aminator將每個服務打包成虛機映像文件(EC2 AMI),每個服務實例都是個EC2實例。

有許多工具可用來進行虛擬機打包,可以使用持續集成服務器(像Jenkins),由它調用Aminator自動將服務打包成EC2 AMI;Packer.io是另外一個自動打包工具,它支持更多的虛擬化技術,像EC2、DigitalOcean、VirtualBox、VMware等。

Boxfuse提供另外一種選擇,它將java應用打包成輕量級的虛擬機映像文件;這種映像文件支持快速打包、快速啓動,有更高的安全性。

CloudNative公司的Bakery產品提供創建亞馬遜虛擬機(EC2 AMIs)的SaaS服務,你可以配置持續集成服務器調用Bakery打包服務,生成虛機映像文件AMI。使用Bakery的好處是,你不用浪費時間設置創建AMI的環境。

單虛擬機單服務實例模式的最大好處是服務實例之間完全獨立,每個實例有固定數量的CPU和內存,不會佔用其他服務的資源;另外一個好處是可以充分利用成熟的雲架構,像AWS就能提供負載均衡、自動伸縮等有用功能;還有一個好處是服務打包成VM之後,成了黑盒,外界無法得知服務採用的技術,部署和管理完全使用虛擬機管理的API,簡化了部署工作。

單虛擬機單服務實例的缺點是資源利用率低,每一個服務獨佔VM,需要單獨的操作系統,一般的雲平臺提供幾種固定大小的內存、CPU等,這會造成資源浪費;另外,雖然雲平臺支持自動伸縮特性,但是很難快速適應變化,這就需要部署人員不斷手工調整VM配置,增加了部署工作量;另外一個缺點是部署速度慢,因爲VM映像文件大,打包、實例化、啓動速度都慢,當然這不是絕對的,也有些輕量級VM解決方案(如Boxfuse);還有一個缺點是創建和管理VM需要進行大量的重複工作,這些工作會分散精力,讓你不能專注於核心業務。

單容器單服務實例

這種模式下,服務運行在自己的容器中。容器是一種操作系統層面的虛擬化技術,可以包含一個或幾個運行在沙箱中的進程;容器中的進程擁有獨立的端口號和文件系統,可以限制容器可使用的CPU和內存資源,有些還支持限定I/O速率;常用的容器技術有Docker和Solaris Zones。下圖展示了這種模式:


使用這種模式,應用被打包成容器映像文件。映像文件包括服務文件和運行服務需要的庫文件。有些容器映像文件包括完整的linux文件系統,有些更輕量級一些。假設需要部署一個Java服務,映像文件需要包括Java運行時環境(可能是Tomcat)和編譯後的Java應用。

打包成映像文件之後,就可以將映像文件部署到一個或幾個主機(物理或虛擬)上,可以使用類似Kubernetes和Marathon的集羣管理工具來管理容器。集羣管理工具將主機(物理或虛擬)看做資源池,它根據容器的資源需求和每個主機的可用資源來決定將容器部署到哪個主機上。

這種模式類似單服務單主機,優點是服務實例之間相互獨立,很容易監控每個服務實例的資源佔用;封裝了服務實現,外部不容易獲得服務的技術細節;可以使用容器管理API管理服務,部署簡單。這種模式跟單服務單主機模式的不同點是,容器映像文件小,打包、啓動速度都特別快。

單服務單容器模式的缺點是容器的基礎設施沒有VM的基礎設施成熟;另外由於同一臺主機上的多個容器需要共享同一套操作系統內核,容器沒有VM安全。另外一個缺點是需要做大量的重複性工作來管理容器映像文件;此外,除非使用託管容器解決方案(如Google Container Engine或Amazon EC2 Container Service(ECS)),否則必須手動管理容器基礎設施以及VM的基礎設施。

無服務器部署

AWS Lambda是一種無服務器部署技術,支持Java、Node.js和Python編寫的服務。服務部署時需要打成ZIP包,上傳到AWS Lambda;還需要提供元數據,定義響應請求的方法名稱。 AWS Lambda自動運行適當數量的服務實例處理服務請求,你只需要按照請求花費的時間和內存付費。這種技術也有侷限性,但是對於開發人員和部署人員而言,不用關心物理服務器、虛機、容器,還是很有吸引力。

Lambda方法是無狀態服務,一般通過調用AWS服務來處理請求。比如,當用戶向S3 bucket上傳一個圖像文件時,調用Lambda方法向DynamoDB的圖像表中插入一條數據,並向Kinesis stream發佈圖像處理事件。Lambda方法也能調用第三方的Web服務。

調用Lambda方法有四種方法:1.使用服務請求直接調用;2.消費AWS服務發佈的事件時,自動調用;3.AWS API網關處理客戶端請求時,自動調用;4.類似Cron計劃,定期調用。

AWS Lambda是部署微服務的簡便方法,基於請求付費意味着你只用在服務真正運行時花錢;另外,由於不用關心IT基礎設施,你可以集中精力處理業務邏輯。

AWS Lambda有明顯的侷限性:它不適合部署運行時間長的服務,比如消費第三方消息的服務,一次服務必須在300秒內完成;服務必須是無狀態的;服務必須支持快速啓動,否則可能因爲超時而被終止。

5.總結

部署微服務架構的應用是件困難的工作,因爲應用可能包含數十個甚至數百個服務,每個服務可能使用不同的語言和架構,每個服務都是一個小型應用(有自己獨特的部署需求、資源需求、伸縮性和監控需求)。有幾種服務部署模式:單主機單服務、單容器單服務、無服務部署(AWS Lambda)。在第七篇,也就是本系列的最後一篇文章中,我們將討論如何將單體應用遷移到微服務架構。

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