Raffaele Spazzoli是紅帽PaaS和DevOps諮詢部架構師,在加入紅帽之前 ,他在超級KeyBank擔任解決方案架構師,實現了將交付週期從3個月變成一週,在本文中,他將以第一視角講述這段神奇的經歷。
來源|《企業開源實踐聯盟通訊》
Raffaele Spazzoli是紅帽PaaS和DevOps諮詢部架構師,在加入紅帽之前 ,他在KeyBank銀行擔任解決方案架構師。他所在的KeyBank銀行是一家擁有190年曆史、近兩萬名員工、遍佈15個州、一千餘分行的銀行,支撐全球多個國家和地區的業務。根據客戶的不同需求,IT團隊針對不同的專案進行開發,但由於在銀行內部存在著大量傳統的IT系統,產品化的敏捷交付難以實現,這些專案的交付週期往往以季度計算,交付週期長,風險大。後來,在Raffaele團隊的實踐下,KeyBank銀行實現了將交付週期變成一週,在本文中,他將以第一視角講述這段神奇的經歷。
起初的費時費力
這是超大型地區銀行KeyBank將每季度向生產環境部署縮短到每週部署的歷程。在這個過程中,我們全部採用開源軟體從WebSphere遷移到Tomcat,並使用OpenShift作為私有Linux容器雲平臺。並且是在數字渠道現代化專案中做到這一點的,這是銀行在當時最重要的專案。
數字渠道現代化專案的基本訴求,是將以Servlet為基礎、在內部MVC框架之上開發完成,並在Java 1.6以及WebSphere 7.x上執行長達15年之久的Java Web應用程式遷移至更為現代的Web體驗,由此建立一款新的移動Web應用。
經過長久的發展擴張,KeyBank銀行原有Web應用程式的維護成本、特別是針對實際SLA要求的調整開銷越來越昂貴。這是一款典型的單體式應用程式,而我們的架構升級目標在於建立新的API層,藉此將表示邏輯(Web或移動)與業務邏輯拆分開來。很明顯,要達成這專案標,我們首先需要實現持續整合與部署流程的全面現代化。
我們最初只能按季度釋出新功能,整個釋出過程費用昂貴、任務艱鉅。之前的釋出方式可以說充滿了“儀式感”——我們還專門整理出一份Excel電子表格,其中囊括約70項手動操作步驟。因為費時費力,工作只能在週末完成,搶在週一上午之前讓系統恢復線上狀態並進行常規業務處理,這給我們帶來了巨大的壓力。
為此,我開始研究像谷歌、亞馬遜、Facebook等科技巨頭是如何管理自己的功能釋出工作。很幸運,我有機會參加Netflix的運營方法研討會。事實證明,從任何一項功能釋出指標來看,如頻率、成本、程式碼完成時間以及程式碼生產部署時間等,這些組織的效率能比我們高兩到三個數量級。
於是,我決定把交付頻率從季度釋出轉化為每週釋出。坦率地講,我對這個目標沒有太認真地考慮,但我一直將它牢記在心。在我看來,銀行數字渠道有希望實現每週釋出。這個速度還沒快到矽谷初創企業那種近乎荒謬的程度,但又已經足夠快,強迫我們必須擺脫以往會議、手動測試加手動釋出那種老派的運作模式。換句話說,這樣的目標足以敦促我們做出改變。
我在專案中扮演的角色是解決方案架構師。為此,我推出了包含完全無狀態REST服務層與兩個前端的新架構:一個是基於AngularsJS的Web應用程式,另一個則是基於Ionic框架的移動應用(與Web應用大體基於相同的程式碼)。
改革進行中
首先,我要求對JDK進行更新(由版本6升級到版本7)。只有JDK完成更新,我才能使用JAX-RS編寫REST服務。運營團隊起初比較抗拒,但在意識到當前版本的JDK即將壽終正寢時,他們果斷著手推進升級工作。整個過程大概用了6個月時間。
我還要求使用Liberty作為應用伺服器。WebSphere在開發人員的膝上型電腦上啟動速度太慢,一般在5到10分鐘左右。考慮到即將開始實施的大專案,我們必須儘可能提高敏捷性與速度表現。有人提到,要想在膝上型電腦上使用Liberty,唯一的可行方案就是繼續在生產應用伺服器上使用WebSphere。這樣的結論令我們難以接受,因為我們單憑直覺就知道提高產次對於加快運營速度的重要意義,否則任何對後續環境棧中的主要元素(IT、QA、生產等)做出變更時,必然會產生大量無法及時修復的bug。
為此,我需要一款分散式快取工具,藉此保證服務層始終保持完全無狀態(而且無會話)。另外,出於效率的考量,我們同樣需要快取的加持。目前還沒有官方支援的分散式快取平臺,但以後一定會有,我們得早點邁出這一步。
以上一切訴求,讓我意識到這條路在規劃階段就存在問題。開發團隊無法以正確的方式表達自己的需求,運營團隊則太過強調維持正常的執行狀態——而在這兩者之間,解決方案架構師也沒能組織起有效的對話,自然不可能以富有成效的方式做出領導與指引。
我覺得需要徹底改變這種模式,並且摒棄交付團隊以前採用的複雜服務請求流程,改為由運營團隊交付基礎架構。另一個需要設立全新基礎架構的團隊。在其中一項研究中,我們發現運營團隊要想建立一套全新的基礎設施,需要滿足大約四百項要求……不說要求本身能不能達成,光是溝通工作就足以拖垮兩邊的團隊。
於是我轉變了思路,覺得交付團隊不妨自行配置基礎設施。我得出的結論是,最好是選擇一套私有云基礎設施。為此,我開始獨立進行研究,探索哪些工具選項最適合這種需求。與此同時,一支小型運營團隊剛剛解決了一堆令人討厭而且長期存在的網路問題。利用這批空閒勞動力,我們正好可以在KeyBank內部嘗試建立私有云。
根據研究,我們確定Kubernetes是目前最理想的容器私有云平臺。因為我們已經意識到容器在技術層面擁有遠超虛擬機器的優勢,所以虛擬機器雲平臺這一選項被直接否決。我們尋找為Kubernetes提供專業支援的機構,最終發現紅帽及其OpenShift平臺是極為可靠的選擇。之後的工作開始順利推進。與紅帽合作之後,我們在4個月內就建立起了生產預覽,並在7個月內開始向第一批客戶提供生產支援。
我們將應用程式從WebSphere遷移到了Tomcat,將REST引擎由Wink轉換為更流行的Jersey(此前在WebSphere中無法使用),而後添加了Hystrix,並向可用性策略中引入了斷路器模式。最後,我們還使用Redis實現了分散式快取。
但技術問題永遠不是最困難的部分。我們的目標是實現每週釋出,因此必須實現基礎設施的自我配置能力與不變性。
持續交付管道實現全面自動化
為了達成這些目標,我們需要為部署在OpenShift中的應用程式定義所有權與支援模式。實際上,如果開發團隊希望以自助方式管理基礎設施,那又該由誰來提供技術支援?在觀察谷歌、Netflix以及Spotify的業務體系後,我們釋出了一套模型,其中由交付團隊負責管理所需的基礎設施(即在容器中新增的內容),而運營團隊則負責保持OpenShift穩定可用——很明顯,一切業務服務的可用性,都將直接由底層OpenShift的可用性所決定。此外,為了保證所有權明確清晰,我們決定將特定專案的OpenShift配置檔案同項目的其餘原始碼統一起來。
我們採用以下邏輯在Jenkins中建立了一個流程:
• 每十分鐘,原始碼repo會接受一次輪詢;一旦出現任何變更,則觸發新的build。
• 此build將執行單元測試以及建立專案Docker映象所需要的其他一系列操作步驟。完成之後,此Docker映象永遠不會進行後續變更。這也是我們實現不變基礎設施的核心要點之一。
• 在解決方案的每個層上單獨進行一系列整合測試。透過隔離,我們可以模擬出依賴項。以此為基礎,我們即可脫離下游依賴項的可用性與測試資料質量,單獨執行一系列測試。這些測試將在臨時環境中執行,這一點在OpenShift中並不難做到。
• 在IT環境中執行一系列整合測試。
• 我們每天在QA環境上部署一次之前成功完成測試的build。QA環境用於手動探索性測試以及手動(後續計劃改為自動)負載測試。
• 最後一步則是每週在生產預覽環境中進行一次部署。這一步需要人工核准。
在生產環境中部署需要KeyBank的多次批准。這些批准以會議形式完成,即人們展示將部署的內容,而高階領導者簽署釋出命令。這個過程不適合我們,因為我們沒有足夠的時間每週舉行三次會議(的確,這需要三個不同部門確信釋出版本的合理性)。我們可以改變這樣的流程,並且同意:如果一個版本僅影響OpenShift內部的元件,我們就自動批准該版本的釋出。
最後一部分工作,就是建立起完整的自動迴歸測試套件。很快,我們從一系列痛苦的錯誤當中認識到,除非擁有完整的迴歸測試覆蓋範圍,否則我們永遠不可能達到每週釋出的目標。具體來講,手動測試團隊的處理速度,跟不上每週釋出帶來的巨量更新內容。
為此,我們以行為驅動型開發(BDD)原則為指引建立起測試框架。我們選擇Cucumber作為DBB工具。Cucumber的最大優勢,在於允許使用者以自然語言(英語或其他語言)編寫測試用例。我們決定發揮這一優勢,由業務分析師團隊負責編寫測試用例。以此為基礎,我們得以並行推進業務程式碼與測試程式碼的開發,而不再像過去那樣必須先完成業務程式碼、之後才能進行(手動或自動)測試。我們還使用Selenium對Web應用進行瀏覽器與作業系統版本測試,並透過Appium對移動應用進行裝置型號及作業系統版本測試。
總結
現在,我們已經對自己的釋出流程擁有更強的信心。每週四上午,我們都能拿出一些最新成果,並透過OpenShift開箱即用的滾動部署功能實現零宕機發布。困擾了我們很多年的問題就這樣被OpenShift的內建功能解決了……我們還啟用了自動規模伸縮功能。透過在負載測試期間對這項功能進行的深入測試,我們意識到現有系統,或者至少在OpenShift中部署的各系統層內,完全可以透過橫向擴充套件為負載峰值提供正確匹配的例項數量。
這在銀行內部被認為是一個優秀的成功故事。下一步,我們將把同樣的流程引入其他專案,逐步將更多工作負載遷移到OpenShift當中。