Chris Richardson微服務翻譯:微服務部署

Chris Richardson 微服務系列翻譯全7篇鏈接:

原文鏈接:Choosing a Microservices Deployment Strategy


動機

部署一個單體應用意味著運行著龐大應用的多個副本,通常需要 N 臺服務器(物理機或虛擬機),在每臺服務器上運行 M 個應用實例。部署單體應用一般并不特別直接,但還是比部署微服務應用簡單。

一個微服務應用包括幾十甚至數百個服務,使用不同的語言和框架寫成,每個服務都是一個擁有特定的部署、資源、擴展性及監控需求的小應用。例如:根據服務需求運行若干個服務實例,而且每個服務實例必須配套提供適當的 CPU、內存 和 I/O 資源。更具挑戰性的是,部署服務還必須快速、可靠、高效。

單主機部署多服務實例

該模式下,需要多臺物理機或虛擬機,在每個主機上部署多個服務實例。這是比較傳統的部署方法。每個服務實例運行在一至多臺主機的端口上,主機通常像照看寵物一樣來管理這些服務。如下圖所示:

這一模式有幾個變型。其中之一就是每個服務對應一個或一組進程。例如:在 Apache Tomcat 服務器上部署 Java 服務實例作為 web 應用,一個 Node.js 服務實例可能包含一個父進程或一至多個子進程。

另一個變型是在一個進程或進程組中運行多個服務實例。例如:在同一臺 Apache Tomcat 服務器中部署多個 Java web 應用,或者在一個 OSGI 容器中運行多個 OSGI 組件。

單主機多服務部署的優點:

1)資源利用率高,多個服務實例共享服務器及操作系統。如果一個進程或進程組運行多個服務實例的話,效率就更高了,比如多個web應用共享同一臺 Apache Tomcat 服務器和 JVM。

2)部署服務實例快,只需將服務拷貝到主機并啟動。如果服務是 Java 編寫的,復制 JAR包 或者 WAR 包;如果是 Node.js 或者 Ruby 等其它語言,拷貝源代碼即可。通過網絡復制這些字節數還是比較小的。

3)由于沒有太多開銷,啟動服務通常很快。如果服務實例運行在同一容器的進程或進程組,可以動態部署到容器或使用重啟容器的方式啟動服務。

不足在于:

1)服務實例之間沒有隔離。雖然可以準確監控每個服務實例的資源使用情況,但是并不能限制每個實例使用的資源,很有可能一個異常的服務實例會消耗掉主機的所有內存和 CPU資源。

2)同一進程運行多個服務實例根本沒有隔離性,所有服務實例共享一個 JVM 堆。一個異常的服務實例能夠輕易的破壞運行在同一進程中的其它服務實例。此外,也無法監控每個服務資源使用的情況。

3)對運維團隊來講,需要了解部署服務的具體細節。服務可能用不同的語言和框架寫成,因而開發團隊必須分享給運維團隊大量的細節。這種復雜性增加了部署中出錯的風險。

每個主機一個服務實例

這一模式有兩種不同實現:每臺虛擬機部署一個服務實例和每臺容器部署一個服務實例。

每臺虛擬機一個服務實例

該模式下,把每個服務打包為一個虛擬機鏡像,例如 Amazon EC2 AMI。每個服務實例(例如 EC2 實例)使用虛擬機鏡像啟動。下圖展示了此模式的結構:

這也是 Netflix 部署視頻流媒體服務的最初方案。Netflix 使用 Aminator 把每個服務實例打包成 EC2 AMI,每個運行的服務實例就是一個 EC2 實例。

有多種工具可用來構建虛擬機鏡像。可以配置持續集成(CI)服務器(例如 Jenkins)來調用 Aminator,把服務打包為 EC2 AMI。Packer.io 是另一個自動化創建虛擬機鏡像的工具,不同于 Aminator,它支持包括 EC2、DigitalOcean、VirtualBox 和 VMware 在內的多種不同虛擬化技術。

Boxfuse 公司使用更加優秀的方式來構建虛擬機鏡像,克服了下面會講到的虛擬機鏡像的不足。Boxfuse 把 Java 應用打包為一個迷你的虛擬機鏡像。這些鏡像能夠快速構建、啟動,由于只暴露了有限的可能被攻擊的端口,所以也更安全。

CloudNative 使用 Bakery 這款 SaaS 工具來創建 EC2 AMI。用戶的微服務通過測試后,能夠配置 CI 服務器調用 Bakery,把服務打包為 AMI。使用 Bakery 這樣的 SaaS 工具意味著你不需要浪費寶貴的時間來設置創建 AMI 的基礎設施。

每臺虛擬機一個服務實例的優點:

  1. 每個服務實例運行互相隔離,有固定的 CPU 和內存,不會占用別的服務的資源。
  2. 能夠充分利用成熟的云服務平臺。AWS 這樣的云平臺提供了負載均衡和自動擴展這樣實用的功能。
  3. 封裝了服務實現的技術細節。一旦服務被打包成虛擬鏡像,就變成了黑盒,虛擬機鏡像的管理 API 就成了部署該服務的 API。部署變得更簡單可靠。

不足:

  1. 資源利用率低。每個服務實例完全占有包括操作系統在內的整個虛擬機。此外,在公有 IaaS 中,固定大小的虛擬機資源沒有被充分利用。
  2. 公有 IaaS 通常依據虛擬機數量收費,不考慮其忙碌還是空閑。AWS 這類的 IaaS 提供了自動擴展,但是很難針快速響應;因而很容易過度調配虛擬機,增加部署花費。
  3. 部署新的服務通常很緩慢。虛擬機鏡像由于其大小的問題,構建過程會比較慢,而且操作系統啟動也要花費一定時間。然而,因為還有 Boxfuse 這樣輕量級的虛擬機存在,這一問題也并非普遍。
  4. 用戶或組織中的其他人要負責大量無差別的沉重的工作。除非使用 Boxfuse 這樣的工具來解決構建和管理虛擬機鏡像這些復雜的事情,否則這種必要且耗時的工作會占用你處理核心業務的時間。

每臺容器一個服務實例

使用每臺容器部署一個服務實例時,每個服務實例運行在自有容器中。容器是操作系統層面的虛擬化機制,一個容器由運行在沙盒中的一個或多個進程組成。從進程的角度看,它們有著自己的端口命名空間和根文件系統。用戶能夠限制容器的內存和 CPU 資源,有些容器還能限制 I/O 速率。容器技術的代表包括 Docker 和 Solaris Zone。下圖展示了這種模式的架構:

使用這種模式時,用戶將服務打包為容器鏡像。一個容器鏡像就是運行服務所需的應用和庫組成的文件系統鏡像。一些容器鏡像還包括完整的 Linux 根文件系統。以部署 Java 服務為例,構建的容器鏡像包括 Java 運行時或者Apache Tomcat 服務器以及編譯好的 Java 應用。

一旦將服務打包為容器鏡像,就可以啟動一到多個容器了。通常一臺物理機或虛擬主機上會運行多個容器,可以使用 Kubernetes 或 Marathon 這樣的集群管理工具來管理容器。集群管理工具把主機看做資源池,根據每個容器需要的資源和每個主機上可用的資源來調度容器。

每臺容器一個服務實例的優點類似虛擬機具有的優勢:

  1. 服務實例之間完全隔離,也能容易的監控每一臺容器的資源消耗。
  2. 與虛擬機類似,容器能夠封裝實現服務的技術細節。容器管理 API 也可用作管理服務的 API。
  3. 不同于虛擬機,容器技術更為輕量,容器鏡像構建速度也更快。比如在筆記本電腦上,只用短短五秒就能把 Spring Boot 應用打包為 Docker 鏡像。由于沒有冗長的操作系統啟動過程,容器啟動也非常迅速。容器啟動,服務就會運行。

不足:

  1. 雖然容器技術正迅速走向成熟,然而相對虛擬機架構來說還略顯青澀。由于容器之間共享同一主機的操作系統內核,因而也沒有虛擬機那么安全。
  2. 管理容器鏡像也是一項繁重的工作。除非使用 Google Container Engine 或 Amazon EC2 這些容器解決方案,否則需要同時管理容器基礎設施和虛擬機基礎設施。
  3. 容器通常部署在按每臺虛擬機定價的基礎設施上,為了處理負載高峰,可能會過度配置虛擬機,從而增加額外的成本。

有趣的是,容器和虛擬機之間的區別變的模糊起來。如前文所述,Boxfuse 能夠快速構建和啟動虛擬機,Clear Container 項目則致力于創建輕量級的虛擬機鏡像,unikernel 技術也引起了大家的注意。Docker 近期(注:2016 年 1 月 21 日)收購了 Unikernel Systems。

Serverless部署

AWS Lambda 就是 serverless 部署技術的范例。它支持 Java、Node.js 和 Python 服務。為了部署一個微服務,你需要把服務打包為 ZIP 文件并上傳到 AWS Lambda,還要提供元數據,指定處理請求的函數名稱。AWS Lambda 自動為微服務運行足夠的實例來處理請求。可以簡單根據每個請求花費的時間和消耗的內存來計費。開發人員無需擔心服務器、虛擬機或容器的各個方面。

Lambda 函數是一個無狀態的服務,通過調用 AWS 服務處理請求。例如,一個 Lambda 函數在一張圖片被上傳到 S3 時候調用,他能在 DynamoDB 表中插入一條記錄,并向 Kinesis stream 發送一條消息來觸發圖片的處理。一個 Lambda 函數也可以調用第三方 web 服務。
有以下四種方法來調用 Lambda 函數:

  • 直接調用,直接使用 web 服務請求
  • 自動調用,自動響應由 S3、DynamoDB、Knesis、或 Simple Email Service 等 AWS 服務生成的事件
  • 自動調用,自動通過 AWS API 網關處理來自應用客戶端的 HTTP 請求
  • 定期調用,通過類似 Cron 的定時任務實現

可以看出,AWS Lambda 是部署微服務的一個便捷的方式。基于請求的定價方式意味著用戶只需要為服務實際運行的業務付費。此外,用戶無需考慮 IT 基礎設施的問題,從而能夠專注于應用的開發。

然而,AWS Lambda 也有一些局限性。它并不適合被用來部署長期運行的服務,比如消費來自第三方消息的服務。請求需要在 300 秒內完成,由于 AWS Lambda 理論上能夠針對每個請求運行單獨的實例,因此服務必須保持無狀態。此外,它還必須用一種支持的編程語言來編寫。服務也需要快速啟動,否則將會超時或停止。

總結

部署一個微服務應用充滿挑戰。應用由幾十個甚至上百個用不同的語言和框架實現的服務所組成,每個服務都是一個擁有獨立部署、資源、擴展和監控需求的微應用。微服務部署的模式有多種,包括單虛擬機單服務實例和單容器單服務實例。另一個有趣的微服務部署方法則是 AWS Lambda,一個 serverless 的方式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容