部署單體應用程式意味著運行一個或多個相同副本的單個較大的應用程式。您通常會在每個伺服器上配置 N 個伺服器(物理或虛擬)並運行 M 個應用程式實例。單體應用程式的部署並不總是非常簡單,但它比部署微服務應用程式要簡單得多。 ...
https://github.com/oopsguy/microservices-from-design-to-deployment-chinese
譯者:http://oopsguy.com
本書內容主要關於如何使用微服務構建應用程式,這是本書的第六章。第一章介紹了微服務架構模式,討論了使用微服務的優點與缺點。之後的章節討論了微服務架構的方方面面:使用 API 網關、進程間通信、服務發現和事件驅動數據管理。在本章中,我們將介紹部署微服務的策略。
6.1、動機
部署單體應用程式意味著運行一個或多個相同副本的單個較大的應用程式。您通常會在每個伺服器上配置 N 個伺服器(物理或虛擬)並運行 M 個應用程式實例。單體應用程式的部署並不總是非常簡單,但它比部署微服務應用程式要簡單得多。
微服務應用程式由數十甚至上百個服務組成。服務以不同的語言和框架編寫。每個都是一個迷你的應用程式,具有自己特定的部署、資源、擴展和監視要求。例如,您需要根據該服務的需求運行每個服務的一定數量的實例。此外,必須為每個服務實例提供相應的 CPU、記憶體和 I/O 資源。更具挑戰性的是儘管如此複雜,部署服務也必須快速、可靠和具有成本效益。
有幾種不同的微服務部署模式。我們首先看看單主機多服務實例模式。
6.2、單主機多服務實例模式
部署微服務的一種方式是使用單主機多服務實例(Multiple Service Instances per Host)模式。當使用此模式時,您可以提供一個或多個物理主機或虛擬主機,併在每個上運行多個服務實例。從多方面來講,這是應用程式部署的傳統方式。每個服務實例在一個或多個主機的標準埠上運行。主機通常被當作寵物對待。
圖 6-1 展示了該模式的結構:
這種模式有幾個變體。一個變體是每個服務實例都是一個進程或進程組。例如,您可以在 Apache Tomcat 伺服器上將 Java 服務實例部署為 Web 應用程式。一個 Node.js 服務實例可能包含一個父進程和一個或多個子進程。
此模式的另一個變體是在同一進程或進程組中運行多個服務實例。例如,您可以在同一個 Apache Tomcat 伺服器上部署多個 Java Web 應用程式,或在同一 OSGI 容器中運行多個 OSGI 軟體包。
單主機多服務實例模式有優點也有缺點。主要優點是其資源使用率相對較高。多個服務實例共用伺服器及其操作系統。如果進程或組運行了多個服務實例(例如,共用相同的 Apache Tomcat 伺服器和 JVM 的多個 Web 應用程式),則效率更高。
這種模式的另一個優點是部署服務實例相對較快。您只需將服務複製到主機並啟動它。如果服務是使用 Java 編寫的,則可以複製 JAR 或 WAR 文件。對於其他語言,例如 Node.js 或 Ruby,您可以直接複製源代碼。在任一情況下,通過網路複製的位元組數都是相對較小的。
另外,由於缺乏開銷,通常啟動一個服務是非常快的。如果該服務是自己的進程,你只需要啟動它即可。如果服務是在同一容器進程或進程組中運行的幾個實例之一,則可以將其動態部署到容器中或者重新啟動容器。
儘管這很有吸引力,但單主機多服務實例模式有一些明顯的缺點。一個主要的缺點是服務實例很少或者沒有隔離,除非每個服務實例是一個單獨的進程。雖然您可以準確地監視每個服務實例的資源利用率,但是您不能限制每個實例使用的資源。一個行為不當的服務實例可能會占用掉主機的所有記憶體或 CPU。
如果多個服務實例在同一進程中運行,那麼毫無隔離可言。例如,所有實例可能共用相同的 JVM 堆。行為不當的服務實例可能會輕易地破壞在同一進程中運行的其他服務。此外,您無法監控每個服務實例使用的資源。
這種方式的另一個重要問題是部署服務的運維團隊必須瞭解執行此操作的具體細節。服務可以用多種語言和框架編寫,因此開發團隊必須與運維交代許多細節。這種複雜性無疑加大了部署過程中的錯誤風險。
正如您所見,儘管這種方式簡單,但單主機多服務實例模式確實存在一些明顯的缺點。現在讓我們來看看可以繞過這些問題部署微服務的其他方式。
6.3、每個主機一個服務實例模式
部署微服務的另一種方式是使用每個主機一個服務實例(Service Instance per Host)模式。當使用此模式時,您可以在主機上單獨運行每個服務實例。這種模式有兩種不同形式:每個虛擬機一個服務實例和每個容器一個服務實例模式。
6.3.1、每個虛擬機一個服務實例模式
當您使用每個虛擬機一個服務實例模式時,將每個服務打包為一個虛擬機(VM)鏡像(如 Amazon EC2 AMI)。每個服務實例都是一個使用該 VM 鏡像啟動的 VM(例如,一個 EC2 實例)。
圖 6-2 展示了該模式的結構:
這是 Netflix 部署其視頻流服務的主要方式。Netflix 使用 Aminator 將每個服務打包為 EC2 AMI。每個運行的服務實例都是一個 EC2 實例。
您可以使用多種工具來構建自己的虛擬機。您可以配置您的持續集成(CI)伺服器(比如 Jenkins)來調用 Aminator 將服務打包為一個 EC2 AMI。Packer 是自動化虛擬機鏡像創建的另一個選擇。與 Aminator 不同,它支持各種虛擬化技術,包括 EC2、DigitalOcean、VirtualBox 和 VMware。
Boxfuse 公司有一個非常棒的方式來構建虛擬機鏡像,其剋服了我將在下麵描述的虛擬機的缺點。Boxfuse 將您的 Java 應用程式打包成一個最小化的 VM 鏡像。這些鏡像可被快速構建、快速啟動且更加安全,因為它們暴露了一個有限的攻擊面。
CloudNative 公司擁有 Bakery,這是一種用於創建 EC2 AMI 的 SaaS 產品。您可以配置您的 CI 伺服器,以在微服務通過測試後調用 Bakery。之後 Bakery 將您的服務打包成一個 AMI。使用一個如 Bakery 的 SaaS 產品意味著您不必浪費寶貴的時間來設置 AMI 創建基礎架構。
每個虛擬機一個服務實例模式有許多優點。VM 的主要優點是每個服務實例運行是完全隔離的。它有固定數量的 CPU 和記憶體,且不能從其他服務竊取資源。
將微服務部署為虛擬機的另一個優點是可以利用成熟的雲基礎架構。如 AWS 之類的雲提供了有用的功能,例如負載平衡和自動擴展。
將服務部署為虛擬機的另一個好處是它封裝了服務的實現技術。一旦服務被打包成一個虛擬機,它就成為一個黑匣子。VM 的管理 API 成為部署服務的 API。部署變得更加簡單、可靠。
然而,每個虛擬機一個服務實例模式也有一些缺點。一個缺點是資源利用率較低。每個服務實例都有一整個 VM 開銷,包括操作系統。此外,在一個典型的公共 IaaS 中,VM 具有固定大小,並且 VM 可能未被充分利用。
此外,公共 IaaS 中的 VM 通常是收費的,無論它們是處於繁忙還是空閑。如 AWS 之類的 IaaS 雖然提供了自動擴展功能,但很難快速響應需求變化。因此,您經常需要過度配置 VM,從而增加部署成本。
這種方法的另一缺點是部署新版本的服務時通常很慢。由於大小原因,VM 鏡像通常構建很慢。此外,VM 實例化也很慢,同樣是因為它們的大小。而且,操作系統也需要一些時間來啟動。但請註意,這並不普遍,因為已經存在由 Boxfuse 構建的輕量級 VM。
每個虛擬機一個服務實例模式的另一個缺點是通常您要(或組織中的其他人)對很多未劃分的重擔負責。除非您使用 Boxfuse 這樣的工具來處理構建和管理虛擬機的開銷,否則這將是您的責任。這個必要而又耗時的活動會分散您的核心業務。
接下來讓我們看看另一種部署更輕量級微服務的替代方式,它也有許多與虛擬機一樣的優勢。
6.3.2、每個容器一個服務實例模式
當您使用每個容器一個服務實例模式(Service Instance per Container)模式時,每個服務實例都在其自己的容器中運行。容器是一個操作系統級虛擬化機制。一個容器是由一個或多個運行在沙箱中的進程組成。從進程的角度來看,它們有自己的埠命名空間和根文件系統。您可以限制容器的記憶體和 CPU 資源。一些容器實現也具有 I/O 速率限制。容器技術的相關例子有 Docker 和 Solaris Zones。
圖 6-3 展示了該模式的結構:
要使用此模式,請將您的服務打包成一個容器鏡像。容器鏡像是由運行服務所需的應用程式和庫組成的文件系統鏡像。一些容器鏡像由完整的 Linux 根文件系統組成。此外它更加輕便。例如,要部署一個 Java 服務,您可以構建一個包含了 Java 運行時的容器鏡像,可能是一個 Apache Tomcat 伺服器和編譯好的 Java 應用程式。
將服務打包成一個容器鏡像後,您將啟動一個或多個容器。通常在每個物理或虛擬主機上運行多個容器。您可以使用集群管理工具(如 Kubernetes 或 Marathon)來管理容器。集群管理工具將主機視為一個資源池。它根據容器所需的資源和每個主機上可用的資源來決定每個容器放置的位置。
每個容器一個服務實例模式模式有優點和缺點。容器的優點與虛擬機的類似。它們將服務實例彼此隔離。您可以輕鬆地監控每個容器所消耗的資源。此外,與 VM 一樣,容器封裝了服務實現技術。容器管理 API 作為管理您的服務的 API。
然而,與虛擬機不同,容器是輕量級技術。容器鏡像通常可以非常快速地構建。例如,在我的筆記本電腦上,將一個 Spring Boot 應用程式打包成一個 Docker 容器只需要 5 秒鐘的時間。容器也可以很快地啟動,因為沒有繁瑣的操作系統引導機制。當一個容器啟動時,它所運行的就是服務。
使用容器有一些缺點。雖然容器基礎架構正在快速發展走向成熟,但它並不像虛擬機的基礎架構那麼成熟。此外,容器不像 VM 那樣安全,因為容器彼此共用了主機的 OS 內核。
容器的另一個缺點是您需要負責容器鏡像管理未劃分的重擔。此外,除非您使用了托管容器解決方案[如 Google Container Engine 或 Amazon EC2 Container Service(ECS)],否則您必須自己管理容器基礎架構以及可能運行的 VM 基礎架構。
此外,容器通常部署在一個按單個 VM 收費的基礎設施上。因此,如之前所述,可能會產生超額配置 VM 的額外成本,以處理負載峰值。
有趣的是,容器和 VM 之間的區別可能會有些模糊。如之前所述,Boxfuse VM 可以很快地構建和啟動。Clear Containers 項目旨在創建輕量級虛擬機。Unikernels 也正在蓬勃發展。Docker 公司於 2016 年初收購了 Unikernel 系統。
還有一個日益流行的 server-less(無伺服器)部署概念,這是一種避免了“在容器中還是在虛擬機中部署服務”問題的方法。接下來我們來看看。
6.4、Serverless 部署
AWS Lambda 就是一個 serverless 部署技術示例。它支持 Java、Node.js 和 Python 服務。要部署微伺服器,請將其打包成 ZIP 文件並將上傳到 AWS Lambda。您還要提供元數據,其中包括了被調用來處理請求(又稱為事件)的函數的名稱。AWS Lambda 自動運行足夠的微服務服務實例來處理請求。您只需根據每個請求所用時間和記憶體消耗來付費。當然,問題往往出現在細節上,您很快註意到了 AWS Lambda 的局限性。但是,作為開發人員的您或組織中的任何人都無需擔心伺服器、虛擬機或容器的任何方面 ,這非常有吸引力,足以令人難以置信。
Lambda 函數是無狀態服務。它通常通過調用 AWS 服務來處理請求。例如,當圖片上傳到 S3 存儲桶時Lambda 函數將被調用,可插入一條記錄到 DynamoDB 圖片表中,並將消息發佈到 Kinesis 流以觸發圖片處理。 Lambda 函數還可以調用第三方 Web 服務。
有四種方法調用 Lambda 函數:
- 直接使用 Web 服務請求
- 自動響應一個 AWS 服務(如 S3、DynamoDB、Kinesis 或 Simple Email Service)生成的事件
- 通過 AWS API 網關自動處理來自應用程式客戶端的 HTTP 請求
- 按照一個類似 cron 的時間表,定期執行
正如您所見,AWS Lambda 是一個便捷的微服務部署方式。基於請求的定價意味著您只需為服務實際執行的工作支付。另外,由於您不需要對 IT 基礎架構負任何責任,因此可以專註於開發應用程式。
然而,其也存在一些明顯的局限性。Lambda 函數不適用於部署長時間運行的服務,例如消耗第三方消息代理消息的服務。請求必須在 300 秒內完成。服務必須是無狀態的,因為理論上,AWS Lambda 可能為每個請求運行一個單獨的實例。他們必須使用受支持的語言之一來編寫。服務也必須快速啟動;否則,他們可能會因超時而終止。
6.5、總結
部署微服務應用程式充滿著挑戰。您可能有數個甚至數百個使用了各種語言和框架編寫的服務。每個應用程式都是一個迷你應用程式,有自己特定的部署、資源、擴展和監視需求。有幾個微服務部署模式,包括每個虛擬機一個服務實例和每個容器一個服務實例模式。部署微服務的另一個有趣的選擇是 AWS Lambda,一種 serverless 方式。在本書的下一章也是最後一章中,我們將介紹如何將單體應用程式遷移到微服務架構。
微服務實戰:使用 NGINX 在不同主機上部署微服務
by Floyd Smith
NGINX 對於各種類型的部署具有許多優勢 - 無論是單體應用程式、微服務應用程式還是混合應用程式(將在下一章介紹)。使用 NGINX,您可以將情報從不同的部署環境中抽象出來併進入 NGINX。如果您使用針對不同部署環境的工具,則有許多應用程式功能以不同的方式工作,但如果使用 NGINX,那麼在所有環境中都可以使用相同的方式進行工作。
這一特性也為 NGINX 和 NGINX Plus 帶來了第二個優勢:通過在多個部署環境中同時運行應用程式來擴展應用程式的能力。假設您擁有和管理著的本地伺服器,但是您的應用程式使用情況正在增長,並且預計將超出這些伺服器可以處理的峰值。如果你已經使用了 NGINX,您就有了一個強大的選擇:擴展到雲端 - 例如,擴展到 AWS 上,而不是購買、配置和保持額外的伺服器來為了防萬一。也就是說,當您的本地伺服器上的流量達到容量限制時,可根據需要在雲中啟動其他微服務實例來處理。
這隻是因使用 NGINX 變得更加靈活的一個例子。維護單獨的測試和部署環境、切換環境的基礎設施、以及管理各種環境中的應用程式組合都變得更加現實和可實現。
NGINX 微服務參考架構被明確設計為支持這種靈活部署,其假設在開發和部署期間使用容器技術。如果您還沒嘗試,可以考慮轉移到容器,還有 NGINX 或 NGINX Plus,以輕鬆地轉移到微型服務,以及面向未來的應用程式、開發和部署靈活性以及人員。
此系列全部譯文
https://github.com/oopsguy/microservices-from-design-to-deployment-chinese