Chris Richardson 微服務系列翻譯全7篇鏈接:
原文鏈接:Choosing a Microservices Deployment Strategy
動機
部署一個單體應用意味著運行著龐大應用的多個副本瓢喉,通常需要 N 臺服務器(物理機或虛擬機)瞻佛,在每臺服務器上運行 M 個應用實例虐急。部署單體應用一般并不特別直接隘梨,但還是比部署微服務應用簡單。
一個微服務應用包括幾十甚至數百個服務猎荠,使用不同的語言和框架寫成铺呵,每個服務都是一個擁有特定的部署、資源井濒、擴展性及監(jiān)控需求的小應用。例如:根據服務需求運行若干個服務實例列林,而且每個服務實例必須配套提供適當的 CPU瑞你、內存 和 I/O 資源。更具挑戰(zhàn)性的是希痴,部署服務還必須快速者甲、可靠、高效润梯。
單主機部署多服務實例
該模式下过牙,需要多臺物理機或虛擬機甥厦,在每個主機上部署多個服務實例纺铭。這是比較傳統的部署方法。每個服務實例運行在一至多臺主機的端口上刀疙,主機通常像照看寵物一樣來管理這些服務舶赔。如下圖所示:
這一模式有幾個變型。其中之一就是每個服務對應一個或一組進程谦秧。例如:在 Apache Tomcat 服務器上部署 Java 服務實例作為 web 應用竟纳,一個 Node.js 服務實例可能包含一個父進程或一至多個子進程撵溃。
另一個變型是在一個進程或進程組中運行多個服務實例。例如:在同一臺 Apache Tomcat 服務器中部署多個 Java web 應用锥累,或者在一個 OSGI 容器中運行多個 OSGI 組件缘挑。
單主機多服務部署的優(yōu)點:
1)資源利用率高,多個服務實例共享服務器及操作系統桶略。如果一個進程或進程組運行多個服務實例的話语淘,效率就更高了,比如多個web應用共享同一臺 Apache Tomcat 服務器和 JVM际歼。
2)部署服務實例快惶翻,只需將服務拷貝到主機并啟動。如果服務是 Java 編寫的鹅心,復制 JAR包 或者 WAR 包吕粗;如果是 Node.js 或者 Ruby 等其它語言,拷貝源代碼即可旭愧。通過網絡復制這些字節(jié)數還是比較小的颅筋。
3)由于沒有太多開銷,啟動服務通常很快输枯。如果服務實例運行在同一容器的進程或進程組垃沦,可以動態(tài)部署到容器或使用重啟容器的方式啟動服務。
不足在于:
1)服務實例之間沒有隔離用押。雖然可以準確監(jiān)控每個服務實例的資源使用情況肢簿,但是并不能限制每個實例使用的資源,很有可能一個異常的服務實例會消耗掉主機的所有內存和 CPU資源蜻拨。
2)同一進程運行多個服務實例根本沒有隔離性池充,所有服務實例共享一個 JVM 堆。一個異常的服務實例能夠輕易的破壞運行在同一進程中的其它服務實例缎讼。此外收夸,也無法監(jiān)控每個服務資源使用的情況。
3)對運維團隊來講血崭,需要了解部署服務的具體細節(jié)卧惜。服務可能用不同的語言和框架寫成,因而開發(fā)團隊必須分享給運維團隊大量的細節(jié)夹纫。這種復雜性增加了部署中出錯的風險咽瓷。
每個主機一個服務實例
這一模式有兩種不同實現:每臺虛擬機部署一個服務實例和每臺容器部署一個服務實例。
每臺虛擬機一個服務實例
該模式下舰讹,把每個服務打包為一個虛擬機鏡像茅姜,例如 Amazon EC2 AMI。每個服務實例(例如 EC2 實例)使用虛擬機鏡像啟動月匣。下圖展示了此模式的結構:
這也是 Netflix 部署視頻流媒體服務的最初方案钻洒。Netflix 使用 Aminator 把每個服務實例打包成 EC2 AMI奋姿,每個運行的服務實例就是一個 EC2 實例。
有多種工具可用來構建虛擬機鏡像素标〕剖可以配置持續(xù)集成(CI)服務器(例如 Jenkins)來調用 Aminator,把服務打包為 EC2 AMI头遭。Packer.io 是另一個自動化創(chuàng)建虛擬機鏡像的工具粪狼,不同于 Aminator,它支持包括 EC2任岸、DigitalOcean再榄、VirtualBox 和 VMware 在內的多種不同虛擬化技術。
Boxfuse 公司使用更加優(yōu)秀的方式來構建虛擬機鏡像享潜,克服了下面會講到的虛擬機鏡像的不足困鸥。Boxfuse 把 Java 應用打包為一個迷你的虛擬機鏡像。這些鏡像能夠快速構建剑按、啟動疾就,由于只暴露了有限的可能被攻擊的端口,所以也更安全艺蝴。
CloudNative 使用 Bakery 這款 SaaS 工具來創(chuàng)建 EC2 AMI猬腰。用戶的微服務通過測試后,能夠配置 CI 服務器調用 Bakery猜敢,把服務打包為 AMI姑荷。使用 Bakery 這樣的 SaaS 工具意味著你不需要浪費寶貴的時間來設置創(chuàng)建 AMI 的基礎設施。
每臺虛擬機一個服務實例的優(yōu)點:
- 每個服務實例運行互相隔離缩擂,有固定的 CPU 和內存鼠冕,不會占用別的服務的資源。
- 能夠充分利用成熟的云服務平臺胯盯。AWS 這樣的云平臺提供了負載均衡和自動擴展這樣實用的功能懈费。
- 封裝了服務實現的技術細節(jié)。一旦服務被打包成虛擬鏡像博脑,就變成了黑盒憎乙,虛擬機鏡像的管理 API 就成了部署該服務的 API。部署變得更簡單可靠叉趣。
不足:
- 資源利用率低泞边。每個服務實例完全占有包括操作系統在內的整個虛擬機。此外君账,在公有 IaaS 中繁堡,固定大小的虛擬機資源沒有被充分利用沈善。
- 公有 IaaS 通常依據虛擬機數量收費乡数,不考慮其忙碌還是空閑椭蹄。AWS 這類的 IaaS 提供了自動擴展,但是很難針快速響應净赴;因而很容易過度調配虛擬機绳矩,增加部署花費。
- 部署新的服務通常很緩慢玖翅。虛擬機鏡像由于其大小的問題翼馆,構建過程會比較慢,而且操作系統啟動也要花費一定時間金度。然而应媚,因為還有 Boxfuse 這樣輕量級的虛擬機存在,這一問題也并非普遍猜极。
- 用戶或組織中的其他人要負責大量無差別的沉重的工作中姜。除非使用 Boxfuse 這樣的工具來解決構建和管理虛擬機鏡像這些復雜的事情,否則這種必要且耗時的工作會占用你處理核心業(yè)務的時間跟伏。
每臺容器一個服務實例
使用每臺容器部署一個服務實例時丢胚,每個服務實例運行在自有容器中。容器是操作系統層面的虛擬化機制受扳,一個容器由運行在沙盒中的一個或多個進程組成携龟。從進程的角度看,它們有著自己的端口命名空間和根文件系統勘高。用戶能夠限制容器的內存和 CPU 資源峡蟋,有些容器還能限制 I/O 速率。容器技術的代表包括 Docker 和 Solaris Zone华望。下圖展示了這種模式的架構:
使用這種模式時层亿,用戶將服務打包為容器鏡像。一個容器鏡像就是運行服務所需的應用和庫組成的文件系統鏡像立美。一些容器鏡像還包括完整的 Linux 根文件系統匿又。以部署 Java 服務為例,構建的容器鏡像包括 Java 運行時或者Apache Tomcat 服務器以及編譯好的 Java 應用建蹄。
一旦將服務打包為容器鏡像碌更,就可以啟動一到多個容器了。通常一臺物理機或虛擬主機上會運行多個容器洞慎,可以使用 Kubernetes 或 Marathon 這樣的集群管理工具來管理容器痛单。集群管理工具把主機看做資源池,根據每個容器需要的資源和每個主機上可用的資源來調度容器劲腿。
每臺容器一個服務實例的優(yōu)點類似虛擬機具有的優(yōu)勢:
- 服務實例之間完全隔離旭绒,也能容易的監(jiān)控每一臺容器的資源消耗。
- 與虛擬機類似,容器能夠封裝實現服務的技術細節(jié)挥吵。容器管理 API 也可用作管理服務的 API重父。
- 不同于虛擬機,容器技術更為輕量忽匈,容器鏡像構建速度也更快房午。比如在筆記本電腦上,只用短短五秒就能把 Spring Boot 應用打包為 Docker 鏡像丹允。由于沒有冗長的操作系統啟動過程郭厌,容器啟動也非常迅速。容器啟動雕蔽,服務就會運行折柠。
不足:
- 雖然容器技術正迅速走向成熟,然而相對虛擬機架構來說還略顯青澀批狐。由于容器之間共享同一主機的操作系統內核液走,因而也沒有虛擬機那么安全。
- 管理容器鏡像也是一項繁重的工作贾陷。除非使用 Google Container Engine 或 Amazon EC2 這些容器解決方案缘眶,否則需要同時管理容器基礎設施和虛擬機基礎設施。
- 容器通常部署在按每臺虛擬機定價的基礎設施上髓废,為了處理負載高峰巷懈,可能會過度配置虛擬機,從而增加額外的成本慌洪。
有趣的是顶燕,容器和虛擬機之間的區(qū)別變的模糊起來。如前文所述冈爹,Boxfuse 能夠快速構建和啟動虛擬機涌攻,Clear Container 項目則致力于創(chuàng)建輕量級的虛擬機鏡像型酥,unikernel 技術也引起了大家的注意乌企。Docker 近期(注:2016 年 1 月 21 日)收購了 Unikernel Systems。
Serverless部署
AWS Lambda 就是 serverless 部署技術的范例瓢对。它支持 Java憋肖、Node.js 和 Python 服務因痛。為了部署一個微服務,你需要把服務打包為 ZIP 文件并上傳到 AWS Lambda岸更,還要提供元數據鸵膏,指定處理請求的函數名稱。AWS Lambda 自動為微服務運行足夠的實例來處理請求怎炊√菲螅可以簡單根據每個請求花費的時間和消耗的內存來計費廓译。開發(fā)人員無需擔心服務器、虛擬機或容器的各個方面债查。
Lambda 函數是一個無狀態(tài)的服務非区,通過調用 AWS 服務處理請求。例如攀操,一個 Lambda 函數在一張圖片被上傳到 S3 時候調用院仿,他能在 DynamoDB 表中插入一條記錄秸抚,并向 Kinesis stream 發(fā)送一條消息來觸發(fā)圖片的處理速和。一個 Lambda 函數也可以調用第三方 web 服務。
有以下四種方法來調用 Lambda 函數:
- 直接調用剥汤,直接使用 web 服務請求
- 自動調用颠放,自動響應由 S3、DynamoDB吭敢、Knesis碰凶、或 Simple Email Service 等 AWS 服務生成的事件
- 自動調用,自動通過 AWS API 網關處理來自應用客戶端的 HTTP 請求
- 定期調用鹿驼,通過類似 Cron 的定時任務實現
可以看出欲低,AWS Lambda 是部署微服務的一個便捷的方式⌒笪基于請求的定價方式意味著用戶只需要為服務實際運行的業(yè)務付費砾莱。此外,用戶無需考慮 IT 基礎設施的問題凄鼻,從而能夠專注于應用的開發(fā)腊瑟。
然而,AWS Lambda 也有一些局限性块蚌。它并不適合被用來部署長期運行的服務闰非,比如消費來自第三方消息的服務。請求需要在 300 秒內完成峭范,由于 AWS Lambda 理論上能夠針對每個請求運行單獨的實例财松,因此服務必須保持無狀態(tài)。此外纱控,它還必須用一種支持的編程語言來編寫游岳。服務也需要快速啟動,否則將會超時或停止其徙。
總結
部署一個微服務應用充滿挑戰(zhàn)胚迫。應用由幾十個甚至上百個用不同的語言和框架實現的服務所組成,每個服務都是一個擁有獨立部署唾那、資源访锻、擴展和監(jiān)控需求的微應用褪尝。微服務部署的模式有多種,包括單虛擬機單服務實例和單容器單服務實例期犬。另一個有趣的微服務部署方法則是 AWS Lambda河哑,一個 serverless 的方式。