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