1. 程式人生 > >微服務實戰(六):選擇微服務部署策略 - DockOne.io

微服務實戰(六):選擇微服務部署策略 - DockOne.io

利用 -- 的區別 box imp 通信 標準 應用打包 email

原文:微服務實戰(六):選擇微服務部署策略 - DockOne.io


【編者的話】這篇博客是用微服務建應用的第六篇,第一篇介紹了微服務架構模板,並且討論了使用微服務的優缺點。隨後的文章討論了微服務不同方面:使用API網關,進程間通訊,服務發現和事件驅動數據管理。這篇文章,我們將討論部署微服務的策略。

本系列文章:

  • 微服務實戰(一):微服務架構的優勢與不足
  • 微服務實戰(二):使用API Gateway
  • 微服務實戰(三):深入微服務架構的進程間通信
  • 微服務實戰(四):服務發現的可行方案以及實踐案例
  • 微服務實踐(五):微服務的事件驅動數據管理


動機

部署一個單體式應用意味運行大型應用的多個副本,典型的提供若幹個(N)服務器(物理或者虛擬),運行若幹個(M)個應用實例。部署單體式應用不會很直接,但是肯定比部署微服務應用簡單些。

一個微服務應用由上百個服務構成,服務可以采用不同語言和框架分別寫就。每個服務都是一個單一應用,可以有自己的部署、資源、擴展和監控需求。例如,可以根據服務需求運行若幹個服務實例,除此之外,每個實例必須有自己的CPU,內存和I/O資源。盡管很復雜,但是更挑戰的是服務部署必須快速、可靠和性價比高。

有一些微服務部署的模式,先討論一下每個主機多服務實例的模式。

單主機多服務實例模式

部署微服務的一種方法就是單主機多服務實例模式,使用這種模式,需要提供若幹臺物理或者虛擬機,每臺機器上運行多個服務實例。很多情況下,這是傳統的應用部署方法。每個服務實例運行一個或者多個主機的well-known端口,主機可以看做寵物。

下圖展示的是這種架構:
技術分享圖片

這種模式有一些參數,一個參數代表每個服務實例由多少進程構成。例如,需要在Apache Tomcat Server上部署一個Java服務實例作為web應用。一個Node.js服務實例可能有一個父進程和若幹個子進程構成。

另外一個參數定義同一進程組內有多少服務實例運行。例如,可以在同一個Apache Tomcat Server上運行多個Java web應用,或者在同一個OSGI容器內運行多個OSGI捆綁實例。

單主機多服務實例模式也是優缺點並存。主要優點在於資源利用有效性。多服務實例共享服務器和操作系統,如果進程組運行多個服務實例效率會更高,例如,多個web應用共享同一個Apache Tomcat Server和JVM。

另一個優點在於部署服務實例很快。只需將服務拷貝到主機並啟動它。如果服務用Java寫的,只需要拷貝JAR或者WAR文件即可。對於其它語言,例如Node.js或者Ruby,需要拷貝源碼。也就是說網絡負載很低。

因為沒有太多負載,啟動服務很快。如果服務是自包含的進程,只需要啟動就可以;否則,如果是運行在容器進程組中的某個服務實例,則需要動態部署進容器中,或者重啟容器。

除了上述優點外,單主機多服務實例也有缺陷。其中一個主要缺點是服務實例間很少或者沒有隔離,除非每個服務實例是獨立進程。如果想精確監控每個服務實例資源使用,就不能限制每個實例資源使用。因此有可能造成某個糟糕的服務實例占用了主機的所有內存或者CPU。

同一進程內多服務實例沒有隔離。所有實例有可能,例如,共享同一個JVM heap。某個糟糕服務實例很容易攻擊同一進程中其它服務;更甚至於,有可能無法監控每個服務實例使用的資源情況。

另一個嚴重問題在於運維團隊必須知道如何部署的詳細步驟。服務可以用不同語言和框架寫成,因此開發團隊肯定有很多需要跟運維團隊溝通事項。其中復雜性增加了部署過程中出錯的可能性。

可以看到,盡管熟悉,但是單主機多服務實例有很多嚴重缺陷。下面看看是否有其他部署微服務方式能夠避免這些問題。

單主機單服務實例模式

另外一種部署微服務方式是單主機單實例模式。當使用這種模式,每個主機上服務實例都是各自獨立的。有兩種不同實現模式:單虛擬機單實例和單容器單實例。

單虛擬機單實例模式

但是用單虛擬機單實例模式,一般將服務打包成虛擬機映像(image),例如一個Amazon EC2 AMI。每個服務實例是一個使用此映像啟動的VM(例如,EC2實例)。下圖展示了此架構:
技術分享圖片
Netfix采用這種架構部署video streaming service。Netfix使用Aminator將每個服務打包成一個EC2 AMI。每個運行服務實例就是一個EC2實例。

有很多工具可以用來搭建自己的VMs。可以配置持續集成(CI)服務(例如,Jenkins)避免Aminator將服務打包成EC2 AMI。packer.io是自動虛機映像創建的另外一種選擇。跟Aminator不同,它支持一系列虛擬化技術,例如EC2,DigitalOcean,VirtualBox和VMware。?

Boxfuse公司有一個創新方法創建虛機映像,克服了如下缺陷。Boxfuse將java應用打包成最小虛機映像,它們創建迅速,啟動很快,因為對外暴露服務接口少而更加安全。

CloudNative公司有一個用於創建EC2 AMI的SaaS應用,Bakery。用戶微服務架構通過測試後,可以配置自己的CI服務器激活Bakery。Bakery將服務打包成AMI。使用如Bakery的SaaS應用意味著用戶不需要浪費時間在設置自己的AMI創建架構。

每虛擬機服務實例模式有許多優勢,主要的VM優勢在於每個服務實例都是完全獨立運行的,都有各自獨立的CPU和內存而不會被其它服務占用。

另外一個好處在於用戶可以使用成熟雲架構,例如AWS提供的,雲服務都提供如負載均衡和擴展性等有用功能。

還有一個好處在於服務實施技術被自包含了。一旦服務被打包成VM就成為一個黑盒子。VM的管理API成為部署服務的API,部署成為一個非常簡單和可靠的事情。

單虛擬機單實例模式也有缺點。一個缺點就是資源利用效率不高。每個服務實例戰友整個虛機的資源,包括操作系統。而且,在一個典型的公有IaaS環境,虛機資源都是標準化的,有可能未被充分利用。

而且,公有IaaS根據VM來收費,而不管虛機是否繁忙;例如AWS提供了自動擴展功能,但是對隨需應用缺乏快速響應,使得用戶不得不多部署虛機,從而增加了部署費用。

另外一個缺點在於部署服務新版本比較慢。虛機鏡像因為大小原因創建起來比較慢,同樣原因,虛機初始化也比較慢,操作系統啟動也需要時間。但是這並不一直是這樣,一些輕量級虛機,例如使用Boxfuse創建的虛機,就比較快。

第三個缺點是對於運維團隊,它們負責許多客制化工作。除非使用如Boxfuse之類的工具,可以幫助減輕大量創建和管理虛機的工作;否則會占用大量時間從事與核心業務不太無關的工作。

那麽我們來看看另外一種仍然具有虛機特性,但是比較輕量的微服務部署方法。

單容器單服務實例模式

當使用這種模式時,每個服務實例都運行在各自容器中。容器是運行在操作系統層面的虛擬化機制。一個容器包含若幹運行在沙箱中的進程。從進程角度來看,他們有各自的命名空間和根文件系統;可以限制容器的內存和CPU資源。某些容器還具有I/O限制,這類容器技術包括Docker和Solaris Zones。

下圖展示了這種模式:
技術分享圖片
?使用這種模式需要將服務打包成容器映像。一個容器映像是一個運行包含服務所需庫和應用的文件系統?。某些容器映像由完整的linux根文件系統組成,其它則是輕量級的。例如,為了部署Java服務,需要創建包含Java運行庫的容器映像,也許還要包含Apache Tomcat server,以及編譯過的Java應用。

一旦將服務打包成容器映像,就需要啟動若幹容器。一般在一個物理機或者虛擬機上運行多個容器,可能需要集群管理系統,例如k8s或者Marathon,來管理容器。集群管理系統將主機作為資源池,根據每個容器對資源的需求,決定將容器調度到那個主機上。

單容器單服務實例模式也是優缺點都有。容器的優點跟虛機很相似,服務實例之間完全獨立,可以很容易監控每個容器消耗的資源。跟虛機相似,容器使用隔離技術部署服務。容器管理API也可以作為管理服務的API。

然而,跟虛機不一樣,容器是一個輕量級技術。容器映像創建起來很快,例如,在筆記本電腦上,將Spring Boot 應用打包成容器映像只需要5秒鐘。因為不需要操作系統啟動機制,容器啟動也很快。當容器啟動時,後臺服務就啟動了。

使用容器也有一些缺點。盡管容器架構發展迅速,但是還是不如虛機架構成熟。而且由於容器之間共享host OS內核因此並不像虛機那麽安全。

另外,容器技術將會對管理容器映像提出許多客制化需求,除非使用如Google Container Engine或者Amazon EC2 Container Service (ECS),否則用戶將同時需要管理容器架構以及虛機架構。

第三,容器經常被部署在按照虛機收費的架構上,很顯然,客戶也會增加部署費用來應對負載的增長。

有趣的是,容器和虛機之間的區別越來越模糊。如前所述,Boxfuse虛機啟動創建都很快,Clear Container技術面向創建輕量級虛機。unikernel公司的技術也引起大家關註,Docker最近收購了Unikernel公司。

除了這些之外,server-less部署技術,避免了前述容器和VM技術的缺陷,吸引了越來越多的註意。下面我們來看看。

Serverless 部署

AWS Lambda是serverless部署技術的例子,支持Java,Node.js和Python服務;需要將服務打包成ZIP文件上載到AWS Lambda就可以部署。可以提供元數據,提供處理服務請求函數的名字(一個事件)。AWS Lambda自動運行處理請求足夠多的微服務,然而只根據運行時間和消耗內存量來計費。當然細節決定成敗,AWS Lambda也有限制。但是大家都不需要擔心服務器,虛擬機或者容器內的任何方面絕對吸引人。

Lambda 函數 是無狀態服務。一般通過激活AWS服務處理請求。例如,當映像上載到S3 bucket激活Lambda函數後,就可以在DynamoDB映像表中插入一個條目,給Kinesis流發布一條消息,觸發映像處理動作。Lambda函數也可以通過第三方web服務激活。

有四種方法激活Lambda函數:
  1. 直接方式,使用web服務請求
  2. 自動方式,回應例如AWS S3,DynamoDB,Kinesis或者Simple Email Service等產生的事件
  3. 自動方式,通過AWS API網關來處理應用客戶端發出的HTTP請求?
  4. 定時方式,通過cron響應?--很像定時器方式


可以看出,AWS Lambda是一種很方便部署微服務的方式。基於請求計費方式意味著用戶只需要承擔處理自己業務那部分的負載;另外,因為不需要了解基礎架構,用戶只需要開發自己的應用。

然而還是有不少限制。不需要用來部署長期服務,例如用來消費從第三方代理轉發來的消息,請求必須在300秒內完成,服務必須是無狀態,因為理論上AWS Lambda會為每個請求生成一個獨立的實例;必須用某種支持的語言完成,服務必須啟動很快,否則,會因為超時被停止。

總結

部署微服務應用也是一種挑戰。用各種語言和框架寫成的服務成百上千。每種服務都是一種迷你應用,有自己獨特的部署、資源、擴充和監控需求。有若幹種微服務部署模式,包括單虛機單實例以及單容器單實例。另外可選模式還有AWS Lambda,一種serverless方法。

在下一篇也是本系列最後一篇?博客中,我們來討論如何將一個單體式應用遷移到微服務架構。

原文鏈接:Choosing a Microservices Deployment Strategy(翻譯:楊峰)

微服務實戰(六):選擇微服務部署策略 - DockOne.io