Gilt如何將微服務部署到AWS環境,介紹ION-Roller

weixin_34253539發表於2015-07-08

經過七年的發展,gilt.com已經從一個使用Ruby on Rails開發的創業公司成長為使用Scala微服務架構的主流電子商務平臺。Gilt的限時搶購商業模式的基礎是:在短時間內會湧入大量的客戶訪問,以競買某些限量的奢侈品。通過使用微服務架構,它為我們的服務提供了可伸縮性、效能以及可靠性的結合,同時也為我們的開發團隊帶來了自治性、自主性以及靈活性。團隊可以自由地選擇程式語言、框架、資料庫以及構建系統,為核心的網站功能、移動應用、個性化演算法、實時資料來源以及通知功能建立服務。\

隨著軟體服務的大爆發,隨之出現的問題是如何部署與執行我們所建立的程式碼。在Gilt發展的早期,它們的軟體執行在“裸機”之上,部署在一個、隨後升級為兩個傳統的資料中心之內。團隊需要申請新的硬體設定,隨後通過自定義指令碼和Capistrano的混合使用進行部署。這種方式雖然能夠運作,但也帶來了很大的困難。對虛擬化技術的首次嘗試表現為在每日的訪問高峰時效能表現不佳,大量的服務最終在同一個物理環境內相互交織在一起,導致了效能方面的異常,並且有時會由於缺乏資源的分離性而導致停機。在訪問高峰時,對於某個服務進行大規模的部署會佔用“每次請求的多個執行緒”,由此造成了整個網站的癱瘓。\

我們曾經嘗試了多種技術,並且建立了各種工具,通過在生產環境中進行測試和持續部署等手段試圖減輕這方面的問題。但經過研究發現,我們用於在資料中心的硬體上分配並自動設定服務的方式已經被證實是一種非常耗時、並且非常困難的方式。\

因此我們開始考慮將微服務基礎設施大規模地轉移到雲環境中,主要是指Amazon Web Services(AWS)環境,並且提煉出不可變部署(Immutable Deployment)這一概念,它是由我們之前在函數語言程式設計中所使用的不可變變數的經驗所啟發的。我們將一套原本基於自身的資料中心打造的工具“ION-Cannon”升級為一套即將開源的工具“ION-Roller”,促使我們開發ION-Roller這套工具的動力在於:\

  • 允許團隊通過宣告式的方式指定如何將他們的服務部署到AWS,例如可用的節點數的最小或最大值、每個例項的大小等等。\
  • 提供一條將服務與應用作為不可變的Docker映象部署到生產環境中的管道,可支援分階段式釋出,並且能夠分階段地將訪問從老版本的服務轉移到新版本的服務上。\
  • 在大型釋出的時候支援快速回滾,能夠使一組已經處於“熱”狀態的例項仍然保持執行之前的版本。

在本文中,我們將談論ION-Roller中的一些核心概念,以及相關的技術和實現途徑,並且簡要地敘述它的使用方式。\

ION-Roller,基於雲的微服務王國

\

我們首先將微服務世界想象成為構建在獨立的、不可變的環境之上的HTTP終結點,通過REST API的方式進行訪問。\

HTTP終結點

\

Gilt使用HTTP作為系統間通訊的傳輸封裝,對於使用者來說,HTTP終結點表現為一個主機名與埠的組合(在它之上還有一個發現層)。我們的想法是,當組織中的軟體與配置隨著時間而演變時,將這個終結點作為一個組織級的概念進行使用。\

雖然這個概念很簡單,但可以實現許多實用的目標。通過對代理與/或網路配置的合理應用,我們就能夠提供以下特性:\

  • 逐步地釋出新的軟體版本\
  • 安全地回滾至之前版本的軟體或配置\
  • 通過錯誤率以及延遲情況的監控,檢測到異常情況的發生\
  • 能夠了解哪些軟體提供了終結點\
  • 能夠了解軟體或配置隨時間進行變更的資訊

在描述環境時配置勝於程式碼

\

在運維規模非常小的情況下,在部署過程中要求得到不受限制的靈活性看起來是一種合理的訴求。但隨著規模的增加,這種方式很快就變得難以管理、監控及理解了。\

宣告式的配置在描述及管理部署方面是一種實用的工具,它能夠以一種結構化的風格進行管理。從配置的角度來說,它能完成的任務比起程式碼來說更為有限,但也因此能夠對請求進行分析與報告。\

在軟體部署中進行風險管理

\

軟體釋出包括了各種權衡:靈活性與簡便性、以及速度與安全性。\

大多數生產環境的發展方向是轉向新的部署流程,這種流程能夠在特性開發或bug修復完成之後在更短的時間之內讓使用者看到這些變更。這也表示對生產環境進行變更的機率更高。由於每次釋出都內含著風險,因此這一策略也有它的不利之處。為了抵消這種不利情況,團隊需要採取一些能夠緩解每次釋出中的風險的釋出流程,讓每次釋出都成為一個日常的、安全的操作。\

風險體現在多個方面:異常的數量和嚴重度、受影響使用者的數量及比例、以及從故障中恢復的時間長短。\

釋出流程對於異常的數量以及異常的嚴重度的影響並沒有開發流程那麼高,但頻繁的釋出通常能夠使找到某個異常發生原因的速度更快(因為每個釋出中的變數數量減少了)。\

我們所能做的就是減少受影響的使用者數量,以及減少修復的時間。在生產環境上進行測試、部分發布以及金絲雀部署(canary release)等方式正適用於這一場景。如果能夠在沒有任何生產環境中訪問的情況下對新的釋出進行測試,那麼就能夠將影響降至最低(甚至為零),但這種方式能夠找到的異常數量也是最少的。由於許多異常情況只在常規的訪問中才會出現,因此一臺金絲雀機器(執行新軟體的一個單一例項)是很有價值的工具,通過它可以瞭解新的釋出是否適於使用。目前為止,對使用者的影響依然是很小的,這取決於你如何對服務進行分片。保持漸進式的釋出過程也是通過將受影響的比例最小化,將bug對使用者的影響降至最低。\

從故障中恢復的時間是不可變軟體方式的一個主要優點,因為舊版本的軟體依然“可用”。一旦發現異常情況,可以以最小的風險在最短的時間內回到之前的舊版本。我們稍後將進一步對不可變部署展開討論。\

執行中軟體的期望狀態以及實際狀態

\

我們希望持續地監控某個終結點背後系統的期望執行狀態以及實際執行狀態的差別。如果這種差別確實存在,那麼我們就應當(逐漸地)讓實際狀態向期望狀態靠攏。我們持續地對執行環境進行大量的測試(包括執行的軟體、負載均衡器設定、DNS等等),如果其中任何一項不能夠滿足需求,就將它替換掉。\

舉例來說,假設我們知道訪問應當由某個特定版本的軟體進行處理,卻發現沒有任何一臺執行這個版本的伺服器是可用的(可以出於任何原因,包括某人無意中移除了這些伺服器),那麼就應當請求進行部署。\

不可變部署

\

“不可變部署”的思想是通過一個已定義的、易於理解的配置部署軟體,而且這個配置不會隨著時間而改變。軟體與配置都是釋出中的自然組成,你不能通過修改資料中的某些地方隨後重啟的方式對軟體進行變更,而是重新生成該軟體的一個副本,讓其中包含經過更新的細節內容。\

這種思想能夠產生更易於預測的環境,並且當某個新發布被證實“有問題”的情況下,能夠回滾至軟體的老版本而無需進行重啟。(即使能夠找到老版本的軟體,在有些情況下要完全啟動它也是一件費時費力的任務,因為它可能需要進行載入快取等工作。)\

在一個小規模的環境中,可能只存在少量的執行伺服器,因此可能只有在釋出完全結束之後,才能夠發現新的釋出中出現的異常情況。在傳統的非不可變釋出場景中,所有舊版本的軟體都已經被替換了。\

不可變部署方式在我們目前的服務中的實現還存在著一點不足之處。因為所有的環境都是按需搭建的,因此搭建時間取決於某些因素,例如啟動新EC2例項的時間、以及下載適當的Docker映象的時間。與之相比,一些其它部署工具要求存在一個機器池,不要求在軟體安裝之前搭建機器。因此我們選擇為可回滾性犧牲了一些低延遲特性,因此在軟體釋出後的初次啟動會有較高的延遲。\

Docker映象

\

在微服務環境中,將工具與程式語言的選擇從部署環境中抽象出來是一種非常實用的概念。它允許個別團隊在開發軟體時具有更多的自治性。雖然這方面的選擇已經有許多,從特定於作業系統的包管理系統 —— 例如RPM,到特定於雲提供商的平臺 —— 例如Packer,但我們最終還是決定用Docker實現這一目標。Docker在選擇部署環境與策略方面提供了很高的靈活性,並且十分符合我們的需求。\

重新發明輪子?

\

當我們在尋找能夠方便地管理基於不可變web伺服器的基礎設施時,所找到的選擇是非常有限的。大多數現有的軟體都是為了便於軟體更新進行優化的,但這不是我們所感興趣的更新方式。我們也希望能夠管理web伺服器流量的整個生命週期,但沒有發現任何一種對這一任務進行優化的選擇。\

另一點需要考慮的是,到底是要求開發者學習並理解某種現有的部署工具集所帶來的價值更高,還是說通過一種無衝突的、簡化的工具,能夠滿足我們將某個特定版本的軟體部署到生產環境中的方式能夠帶來更高的生產力。我們相信,開發者應當能夠簡單地釋出軟體,而無需理解複雜的底層機制(同時也保留進行自定義的可能性,這在一些高階場景中是必需的)。\

不什麼不選擇Puppet、Chef等工具

\

許多工具採取的都是以機器為中心的視角,配置是在每一臺機器的基礎上完成的。我們則採取了系統狀態這一更廣泛的視角(比如我們需要某個軟體的四個拷貝以提供服務),而並不太關心個別機器的情況。我們利用了AWS所提供的高層概念,例如將機器執行情況檢查時總是失敗的那些機器進行替換,以及當HTTP終結點的訪問量激增的情況下動態地擴充套件它的能力等等。\

為什麼不選擇CodeDeploy

\

CodeDeploy是一套由Amazon提供的軟體釋出管理系統,但它無法滿足我們支援不可變基礎設施的需求。雖然很容易搭建指令碼,使用CodeDeploy釋出軟體,但你需要預先搭建你的環境。此外,CodeDeploy本身沒有內建的部署Docker映象的功能。\

為什麼不選擇簡單的Elastic Beanstalk

\

Elastic Beanstalk提供了建立環境的各種功能,它允許你執行Docker映象,並且建立大量的支援性系統,例如EC2例項、負載均衡器、自動擴充套件組(根據訪問量改變伺服器的數量)。它還允許對日誌檔案的訪問,並且可以對這些系統進行一定程度的管理工作。\

但是,它對於“不可變部署”概念的支援非常有限,對於某部分軟體的多次釋出將為同一個使用者可見的終結點帶來大量的訪問量,然後逐漸地轉移訪問量。對於這一點,它唯一支援的能力就是“切換CNAMEs”,這是一種非常粗糙的轉移訪問量的方式,因為所有的訪問量都會瞬間轉移到新的環境中。此外,出於DNS的本質,它在可靠性方面也存在問題,因為DNS查詢結果在DNS進行變更後依然會被快取一段時間,並且某些糟糕的客戶端會忽略DNS TTL值,導致訪問量依然在很長的一段時間內會被髮送給舊的環境。\

此外,Elastic Beanstalk沒有提供某種高層次的結構,以幫助你理解在某個終結點的背後有哪些東西執行在生產環境上。“有哪些執行正在執行,它們的配置情況又是怎樣的”這一問題並不容易解答,需要某些高層次的系統輔助。\

我們決定利用Elastic Beanstalk作為一種實用的方法以部署Docker軟體,但需要有層次地進行適當的管理,並且對它的層次進行控制,以便為使用者提供一個完整的工作流。\

介紹ION-Roller

\

ION-Roller是一套服務(包含API、web應用和命令列介面),它利用了Amazon的Elastic Beanstalk及其底層的CloudFormation框架的功能,將Docker映象部署到EC2例項中。\

開始使用ION-Roller,你需要進行一些簡單的操作

\

啟動部署軟體過程的全部工序如下:\

  • 準備一個AWS帳號,並在ION-Roller中為其授權,它能夠為你啟動例項並訪問資源(如果你的組織在執行軟體時使用了多個AWS帳戶執行,ION-Roller能夠為所有這些帳號提供一個單一的部署視角,只需具有足夠的許可權即可)。\
  • 由某個Docker registry(可以選擇hub.docker.com,或使用私有Docker registry服務)提供的Docker映象\
  • 準備軟體的部署規格說明,包括HTTP終結點、EC2例項的數量與型別、Docker映象的執行時引數、環境變數、安全設定等等。它們將作為你的服務配置的一部分提供,並通過REST API提交至ION-Roller。

如果想了解使用AWS帳戶安裝ION-Roller的細節與完整的文件,敬請期待即將開源的這個專案https://github.com/gilt/ionroller。\

使用ION-Roller部署軟體

\

你可以通過內建的命令列工具簡單地啟動部署過程:\

ionroller release \u0026lt;SERVICE_NAME\u0026gt; \u0026lt;VERSION\u0026gt;\

這個工具能夠在釋出過程中提供即時的反饋資訊:

[INFO] NewRollout(ReleaseVersion(0.0.17))\[INFO] Deployment started.\[INFO] Added environment: e-k3bybwxy2f\[INFO] createEnvironment is starting.\[INFO] Using elasticbeanstalk-us-east-1-830967614603 as Amazon S3 storage bucket for environment data.\[INFO] Waiting for environment to become healthy.\[INFO] Created security group named: sg-682b430c\[INFO] Created load balancer named: awseb-e-k-AWSEBLoa-A4GOD7JFELTF\
\

你也可以選擇以程式設計的方式觸發一次部署過程,ION-Roller提供了一套REST API,可以對你的配置和釋出過程進行完全控制。\

在系統的背後,ION-Roller會觸發一個Elastic Beanstalk部署流程,充分地利用了它的功能,包括建立一個負載均衡器、安全以及自動擴充套件組、設定CloudWatch監控,並從某個Docker registry中獲取特定的Docker映象。\

訪問重定向

\

一旦ION-Roller檢測到部署成功之後,它就能夠安全地逐漸將訪問從老版本轉移到新版本的服務。\

訪問的重定向是通過對EC2例項的修改實現的,它能夠通過負載均衡器對HTTP請求進行響應。隨著釋出的流程推進,新部署的例項會逐漸加入負載均衡器的配置中,而原先部署的例項會逐步被刪除。這一流程的啟動時機是可配置的。\

漸進式的訪問重定向使你能夠對最近的釋出進行監控、快速地檢測到失敗、並在必要時進行回滾。\

f7e757defc4636c5fd4e810fa05c3f4a.png

\

軟體回滾

\

由於在釋出過程中,老的環境依然可訪問,老版本的軟體也依然在執行中,因此我們可以安全地將軟體回滾到之前的某個老版本。無用的舊例項在一段時間(可配置)之後才會被移除,由於這段延遲的存在,因此我們在釋出全部完成之後的一段時間內仍然可以選擇回滾。\

我們的目標是持續地監控終結點的執行情況,並且在檢測到異常的情況下自動地回滾到老的版本。我們將使用Amazon的CloudWatch警告功能發出一個即將進行回滾操作的訊號。\

進行手動回滾非常簡單,執行以下指令碼即可:\

ionroller release \u0026lt;SERVICE_NAME\u0026gt; \u0026lt;PREVIOUS_VERSION\u0026gt;\

如果舊的例項仍然可用,那麼只需幾秒鐘的時間即可將訪問全部轉回老版本上。當然,前提是你沒有進行任何使老版本的軟體不可用的操作(例如更新資料儲存系統的schema等等)。如果你希望依靠這種能力以回滾軟體,那麼牢記這一點是非常重要的,無論你使用的是哪一種部署系統。\

金絲雀釋出以及在生產環境中測試

\

ION-Roller通過對訪問轉移流程的配置,支援金絲雀釋出的概念。當有新的版本部署到一些初始的例項之後,該流程就會停止,可以對生產環境中的訪問進行一些釋出測試。在一段可配置的時間之後,釋出流程將會繼續推進。\

89d98eb4940af06b1efa29d6ef6532d4.png

\

在生產環境進行測試

\

對於某些用例,你希望能夠對新的軟體進行測試(或演示),而又不希望產生實際的訪問,那麼我們需要ION-Roller搭建一個分離的HTTP終結點,在生產環境的終結點更新之前,可以通過它處理請求。\

01a1a4338a71590d957bb7ca8f956170.png

\

留意系統狀況 - ION-Trail

\

ION-Roller能夠檢視某個終結點背後的環境與軟體隨著時間推移產生的變化,在對環境進行監控或進行變更的過程中,它將記錄與環境生命週期或部署活動相關的事件。可以通過這一功能實現系統的審計、監控以及報表功能。ION-Trail是一個支援性的服務,為所有被記錄的部署活動提供了一個事件源。\

結論 ——去中央化的DevOps

\

希望讀者在閱讀本文後能夠對於我們將微服務架構部署到AWS的思想有所瞭解。ION-Roller允許我們將整個DevOps組織實現去中央化,並且通過宣告式的部署讓工程師更易於掌握。ION-Roller允許我們進行分階段的釋出與熱回滾,並且支援諸如“金絲雀釋出”與“在生產環境中測試”等特性。如果想了解更多的資訊,請關注Gilt Tech部落格(http://tech.gilt.com),我們很快就會在部落格上宣佈ION-Roller開源專案的公開發布。\

關於作者

\

861960650ad45a307370c50520fafb59.pngNatalia Bartol曾在IBM擔任Eclipse支援工程師從事改善開發者工具的工作,隨後在Zend Technologies擔任Eclipse開發人員及團隊主管。如今她在Gilt擔任軟體工程師,專注於微服務的部署以及提高開發者的生產力。Natalia擁有波茲南科技大學軟體工程專業的理科碩士證書。\

\

47c89a578e05b3cc444dfe7a8da2b9f3.pngGary Coady是來自Gilt Groupe的一位高階軟體工程師,他的工作是自動化部署、編寫構建工具以及傳授Scala技術。他之前曾在Google擔任網站可靠性工程師,將大量時間用於剖析、管理以及處理大規模環境中的運維異常。Gary擁有都柏林大學聖三一學院電腦科學專業的學士學位(Mod)。

\

5930e9fe7fc9cb79dab7aacb586b9094.pngAdrian Trenaman在位於愛爾蘭都柏林的gilt.com擔任工程師高階副總裁。他擁有愛爾蘭國立梅努斯大學電腦科學專業的博士學位,和愛爾蘭管理學院的商業開發專科文憑,以及都柏林大學聖三一學院電腦科學專業的學士學位(Mod. Hons)。

\

檢視英文原文:Deploying Microservices to AWS at Gilt: Introducing ION-Roller

\\

立即免費註冊AWS賬號,獲得12個月免費套餐:點選註冊

\\

有云計算問題?立刻聯絡AWS雲端計算專家:立即聯絡

相關文章