微服務(wù)轉(zhuǎn)型與DevOps
分享人:鄭云龍 睿云智合持續(xù)交付產(chǎn)品負責(zé)人,在敏捷和DevOps領(lǐng)域有豐富經(jīng)驗的實踐,過去作為敏捷和DevOps技術(shù)教練向多家大型企業(yè)提供咨詢和培訓(xùn)服務(wù)。 微服務(wù)轉(zhuǎn)型與DevOps 1 遺留的現(xiàn)狀 在開始微服務(wù)和DevOps主題之前,首先看看在過去我的咨詢工作中,對于大部分咨詢客戶而言,企業(yè)會邀請外部的顧問來對團隊進行改進,最主要的原因都是由于現(xiàn)有的研發(fā)體系和產(chǎn)品團隊,難以跟上市場的變化,希望通過外部顧問,通過一些手段來提高產(chǎn)品團隊的響應(yīng)力。敏捷實踐亦或是DevOps實踐最終的目的都是為了能夠快速的交付高質(zhì)量的軟件產(chǎn)品。 究其原因,為什么這類客戶會有如此大的需求去引入敏捷或者DevOps呢?遺留系統(tǒng)。 歷史遺留問題與新問題,新需求的持續(xù)混合發(fā)酵,導(dǎo)致系統(tǒng)的開發(fā)效率無法滿足業(yè)務(wù)的發(fā)展需求。所以經(jīng)常會有如上圖這種對話。無論是新的需求,還是遺留的Bug都嚴重受制于遺留系統(tǒng) 如果從技術(shù)角度來看,對于遺留系統(tǒng)最主要的問題包括:高耦合性,底可測試行,代碼質(zhì)量差,圈復(fù)雜度高,并且很難對系統(tǒng)進行優(yōu)化。而這些東西我們都可以稱之為技術(shù)債。 而這些技術(shù)債務(wù)的積累最終導(dǎo)致我們的系統(tǒng)越來越難以維護。舉個例子,在之前對客戶團隊進行敏捷技術(shù)培訓(xùn)時,嘗試在項目中使用TDD,最終的結(jié)果是在使用TDD的同時,我們進行了大量的重構(gòu),才能保證我們能夠順利的給某一個業(yè)務(wù)場景添加上相應(yīng)的測試代碼。 而技術(shù)債不是一開始就有的東西,對于傳統(tǒng)單體架構(gòu)而言,在項目初期系統(tǒng)通常也是易于開發(fā),易于部署,易于測試的。 隨著時間和項目演進,系統(tǒng)的代碼量以及復(fù)雜度呈指數(shù)型增長,最終導(dǎo)致我們整個項目的交付周期越來越長,同時系統(tǒng)很難進行擴展,并且當(dāng)擴展時所需要的成本也越來越高。 對于新加入團隊的成員,也需要花費大量的時間了解業(yè)務(wù)背景,熟悉應(yīng)用程序的業(yè)務(wù),配置本地開發(fā)環(huán)境等等。這些看似簡單的任務(wù),往往需要花費大量的時間。 同時對于傳統(tǒng)單體架構(gòu)隨著時間和項目的演進,嘗試引入新技術(shù)或者對現(xiàn)有技術(shù)框架進行改進的成本和風(fēng)險也越來越高。 而對于傳統(tǒng)的SOA架構(gòu)? 如果用直白一點的話來說,就是專注于使用ESB來集成企業(yè)內(nèi)的各個單體應(yīng)用。而往往導(dǎo)致的結(jié)果是兩個大的中心化,技術(shù)的中心化,以及流程的中心化。 由于EBS通常基于特定的技術(shù)棧,并且使用了中心化的標準個規(guī)范,使得業(yè)務(wù)難以根據(jù)業(yè)務(wù)場景去選擇合適的技術(shù)。 而ESB也往往嵌入了大量的業(yè)務(wù)流程,所以導(dǎo)致任何服務(wù)的修改都需要進過復(fù)雜的流程,修改系統(tǒng)的工作量不減反增,維護成本和產(chǎn)品成本也呈非線性增長。 2 什么是微服務(wù)架構(gòu) 通常而言我們對于微服務(wù)并沒有一個準確的定義,但是我們可以認為,微服務(wù)就是我們?nèi)ヒ哉_的姿勢去實現(xiàn)SOA。 對于微服務(wù)通常具有以下特性:獨立進程,獨立部署,獨立技術(shù)以及獨立團隊。 對于每一個服務(wù)而言都是以開發(fā)一個小的獨立的應(yīng)用系統(tǒng),并且每個服務(wù)都是運行在自己的進程中;這些服務(wù)圍繞業(yè)務(wù)功能進行構(gòu)建,并且能夠獨立的部署和發(fā)布;同時服務(wù)與服務(wù)之間可以使用不同的技術(shù)語言以及存儲技術(shù);而對于每一個微服務(wù)都是由一個充分獨立自治的團隊進行端到端的管理,從開發(fā),構(gòu)建,部署,上線運維。并且這些服務(wù)之間通常采用一些輕量級的通訊接口包括像Rest API以及消息隊列 而對于每一個微服務(wù)而言我們都可以根據(jù)其不同的業(yè)務(wù)場景去選擇適合的技術(shù),并且這些服務(wù)之間可以有不同的發(fā)布節(jié)奏 除了技術(shù)上的去中心化,在團隊組織結(jié)構(gòu)上,每一個微服務(wù)團隊都應(yīng)該具有和當(dāng)前業(yè)務(wù)功能開發(fā)所需的全方位技術(shù),及所謂的全功能團隊。這些團隊圍繞著各自的業(yè)務(wù)管理相關(guān)的服務(wù)。相比于傳統(tǒng)的通過組件的方式拆分團隊,微服務(wù)團隊可以端到端的完成特性交付,減少由于將特性分配給多個團隊而導(dǎo)致的溝通問題,系統(tǒng)集成問題,能夠更加快速的交付所需的特性,減少等待時間。 同時微服務(wù)架構(gòu)能夠幫助我們快速的開辟新的渠道,助力企快速獲取市場機會。 剛才談了很多關(guān)于微服務(wù)本身的特性,以及能夠為我們帶來的好處。但是事無好壞,對于任何一家公司和組織,在轉(zhuǎn)向微服務(wù)之前都應(yīng)該明白它為我們帶來的潛在的挑戰(zhàn)。 微服務(wù)化帶來的挑戰(zhàn)? 運維的挑戰(zhàn)?、質(zhì)量保證體系、分布式系統(tǒng)的復(fù)雜度 首先我們來說關(guān)于質(zhì)量的部分 對于任何傳統(tǒng)意義上的測試保障體系,我們通常會通過單元測試,API測試,系統(tǒng)集成測試,以及其他的非功能性測試,諸如性能測試,安全測試等來保證我們軟件交付的質(zhì)量。在敏捷測試實踐中我們通常以測試金字塔的方式來評估我們現(xiàn)有系統(tǒng)的自動化測試水平以及合理性。 那在微服務(wù)中呢?剛才我們已經(jīng)說過,微服務(wù)是一組獨立的去中心化得服務(wù),服務(wù)和服務(wù)之間必然存在相應(yīng)的依賴關(guān)系。 在這里我們仿照敏捷測試金字塔的方式將微服務(wù)的質(zhì)量保證體系劃分為3層:服務(wù)內(nèi),服務(wù)間,以及服務(wù)集成。 相比與過去的軟件質(zhì)量保證體系,我們增加了契約測試來保證服務(wù)和服務(wù)之間的依賴,確保各個服務(wù)是能夠獨立的進行演進升級的。對于契約測試目前包括像Thoughtworks開源的契約測試工具Pact以及Swagger這樣的工具都能夠幫助我們將契約測試添加到我們的質(zhì)量保證體系中。 當(dāng)然對于所有的自動化的質(zhì)量保證過程,我們都應(yīng)該將他們納入到CI流水線中,通過自動化的方式來保證我們每一次代碼變更都是能夠滿足質(zhì)量要求的。 那對于運維體系而言呢? 運維體系面臨的挑戰(zhàn) 1,部署環(huán)境的多樣性,對于傳統(tǒng)團隊的Ops人員,他通常都是接觸一些固定的技術(shù)棧相關(guān)的運維和管理工作,但是在服務(wù)下,每一個服務(wù)都都可能采用不同的技術(shù),數(shù)據(jù)庫,以及中間件。那對于Ops人員而言所需要面臨管理和運維的環(huán)境的復(fù)雜度和難度也隨著服務(wù)化得進程變得越來越困難 2,對于公司而言從開發(fā),測試到部署上線,我們通常需要使用大量的服務(wù)器資源來保證我們各個環(huán)節(jié)的部署環(huán)境需求。舉例來講,在敏捷當(dāng)中我們通常會有Dev環(huán)境,UAT環(huán)境,Prod環(huán)境去提供軟件交付過程中各個階段的部署需求。但是微服務(wù)之后我們可能有幾個,幾十個甚至幾百個不同的服務(wù),而這些服務(wù)都需要相應(yīng)的部署資源,同時如何保證各個階段的環(huán)境一致性問題 3,CI維護成本暴增,在過去我們通常會花費通常一個迭代的時間來搭建我們項目的CI基礎(chǔ)設(shè)施,但是現(xiàn)在隨著服務(wù)數(shù)量的增加我們管理和配置Jenkins的成本也越來越大 4,除此之外包括,日志,監(jiān)控,彈性,高可用都是我們在微服務(wù)轉(zhuǎn)型過程需要面臨的挑戰(zhàn)。 如何解決 充分授權(quán)團隊 在微服務(wù)下我們希望每一個團隊都是能夠充分獨立和自治的。但是往往對于企業(yè)而言對于基礎(chǔ)設(shè)施環(huán)境的管控要求其實非常高,包括像網(wǎng)絡(luò),安全等等。 所以往往對于一個團隊想要獲取一個服務(wù)器資源通常需要復(fù)雜的審批以及配置過程。 而通過引入像Rancher這樣的輕量級的容器化管理平臺,我們可以將底層基礎(chǔ)設(shè)施的管理問題交給專門的運維團隊來進行處理。這些基礎(chǔ)設(shè)施可以是物理機,IaaS,甚至是容器集群。并且將這些資源按照環(huán)境的形式分配給不同的團隊,充分授權(quán)團隊,管理自己的所有的開發(fā),構(gòu)建與部署環(huán)節(jié)。 基礎(chǔ)設(shè)施代碼 而對于持續(xù)集成流水線,以及持續(xù)交付流水線的管理和配置,Jenkins2.0通過Pipeline As Code的方式通過編寫DSL來幫助我們實現(xiàn)全面的基礎(chǔ)設(shè)施及代碼的要求。 在代碼庫當(dāng)中及包含源代碼src,也包含我們的環(huán)境準備過程Dockerfile以及環(huán)境定義docker-compose.yml. rancher-compose.yml. 同時我們將我們的持續(xù)交付流水線也通過Jenkinsfile的形式保存在源代碼庫中,那么只要我們獲取了軟件倉庫的代碼,就能夠獲取支撐我們軟件交付各個階段的所有物品,包括源代碼以及運行時環(huán)境。并且對于任何代碼或者環(huán)境的變更都能夠通過持續(xù)交付流水線進行持續(xù)的驗證和反饋 同時Rancher也提供了內(nèi)置的監(jiān)控功能:包括主機以及容器。通過Catalog我們也能快速的搭建ELK的日志分析平臺以及其他的監(jiān)控服務(wù)。 通過服務(wù)容器化,以及引入諸如Rancher這樣的容器管理平臺。我們可以使我們的研發(fā)團隊更加專注于軟件架構(gòu)以及環(huán)境架構(gòu)的設(shè)計,而將一些其他的運維和管理工作交給容器管理平臺來管理。能有效的減少我們在DevOps實踐當(dāng)中的成本,包括人員能力以及自動化能力的要求。 同時對于微服務(wù)團隊而言,我們基于持續(xù)交付流水線能夠使軟件交付各個階段的人員能夠有效的協(xié)同工作,保證我們能夠又快又安全的交付軟件,每一次代碼變更都能夠產(chǎn)生一個可工作的軟件(當(dāng)然前提是這些人都是屬于同一個團隊) 所以對于轉(zhuǎn)型微服務(wù)而言,我們需要明白持續(xù)交付以及DevOps文化是支撐我們微服務(wù)轉(zhuǎn)型的一個重要手段。 我們需要有獨立自治的全功能型團隊,通過引入虛擬化技術(shù),容器化技技術(shù),以及相應(yīng)的管理平臺來減少我們部署和運維的復(fù)雜度。并且通過更加完善的質(zhì)量保證體系來確保我們的服務(wù)能夠確實的去支撐我們的軟件交付質(zhì)量。 總結(jié) 就像開篇說的一樣,“微服務(wù)可能是實現(xiàn)SOA的最正確的姿勢”,它實際上是我們軟件交付領(lǐng)域大量優(yōu)秀實踐的一個集合。同時微服務(wù)是不銀彈,在引入微服務(wù)后我們同時需要面對更多復(fù)雜的問題。 通過引入容器化,以及容器化管理平臺能夠減少我們在轉(zhuǎn)型微服務(wù)過程中的大量成本;通過小步嘗試,積累經(jīng)驗和能力,能夠幫助我們在微服務(wù)化轉(zhuǎn)型中走的更加順暢; 同時根據(jù)不同的業(yè)務(wù)模式選擇不同的微服務(wù)重構(gòu)模式能夠幫組我們能夠在解決現(xiàn)有問題的同時來全面提升我們整個產(chǎn)品的響應(yīng)力; 最后一張圖,簡單總結(jié)了一下微服務(wù)中關(guān)于實踐與設(shè)計模式的概覽,希望能夠?qū)Υ蠹以诜?wù)化轉(zhuǎn)型中提供幫助; 最后在準備這次分享的過程中我準備了一些例子,包括Jenkins2的容器化,以及基于Jenkins2和Rancher實現(xiàn)端到端的持續(xù)交付過程: https://github.com/yunlzheng/rancher-jenkins2 https://github.com/yunlzheng/jpetstore-6 有興趣的同學(xué)可以進行參考,當(dāng)中不完善的部分也希望能夠提供反饋,能夠進行相應(yīng)的改進。...
Read More