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