???
作者丨崔皓
策劃丨孫淑娟
【51CTO.com原創(chuàng)稿件】業(yè)務(wù)的飛速發(fā)展以及變化多端的動(dòng)態(tài)組合一直推著以 IaaS、PaaS 和 SaaS 形式表現(xiàn)的云計(jì)算不斷發(fā)展,隨之微服務(wù)的實(shí)施方案也需要與時(shí)俱進(jìn)。
放眼業(yè)內(nèi),谷歌、沃爾瑪和亞馬遜等科技巨頭都開始不同程度地使用微服務(wù)架構(gòu)和方案,他們期待通過微服務(wù)提供的模塊化方案作為業(yè)務(wù)流程再造的基石,適應(yīng)更加靈活復(fù)雜的商業(yè)場景。
從單體架構(gòu)到微服務(wù)架構(gòu)
單體軟件架構(gòu)使用單一的方法和模型構(gòu)建應(yīng)用體系,雖然通過分成的方式將應(yīng)用與應(yīng)用之間進(jìn)行隔離,并且在業(yè)務(wù)邏輯上面便于理解,同時(shí)具備開發(fā)周期可控的特點(diǎn),但單體架構(gòu)的可擴(kuò)展性一直是大家詬病的缺點(diǎn)。
單體架構(gòu)由于其自身特點(diǎn)對(duì)于擴(kuò)展性有多種限制,例如資源可用較差、需要更長的部署周期、無法持續(xù)交付、技術(shù)棧單一無法發(fā)揮技術(shù)多樣性帶來的優(yōu)勢,同時(shí)架構(gòu)中單個(gè)應(yīng)用的故障會(huì)影響到整體軟件。
企業(yè)期待采用模塊化和動(dòng)態(tài)組合的方法來解決以上問題,因?yàn)槟K的動(dòng)態(tài)組合對(duì)于靈活復(fù)雜的業(yè)務(wù)邏輯更具備業(yè)務(wù)推動(dòng)力。
這正應(yīng)了 Adrian Cockcroft,Battery Ventures,說的那句話:
“微服務(wù)是具備有限上下文、松散耦合、面向服務(wù)的架構(gòu)?!?/strong>
松耦合模塊會(huì)根據(jù)應(yīng)用程序的需求進(jìn)行合理組合。每個(gè)服務(wù)可以通過不同的技術(shù)棧來實(shí)現(xiàn),并且可以獨(dú)立擴(kuò)展,從而應(yīng)對(duì)業(yè)務(wù)的調(diào)整。這就意味著服務(wù)之間是需要協(xié)同工作的,一個(gè)應(yīng)用的輸出會(huì)變成另一個(gè)應(yīng)用的輸入,服務(wù)之間也可以通過 API 進(jìn)行有效通訊。同時(shí),由于微服務(wù)的隔離機(jī)制,導(dǎo)致每個(gè)服務(wù)都可以進(jìn)行有效的安全監(jiān)控。例如使用 Python 開發(fā)的服務(wù)就不需要其他技術(shù)能力的支持,這種情況在微服務(wù)開發(fā)中普遍存在。
雖然服務(wù)內(nèi)部的技術(shù)各有不同,到協(xié)同工作時(shí),服務(wù)以及對(duì)外界的接口和傳輸方式卻可以統(tǒng)一規(guī)定。例如使用 (REST) API 的方式進(jìn)行服務(wù)之間的溝通,使用 HTTP 協(xié)議傳輸數(shù)據(jù),利用統(tǒng)一資源標(biāo)識(shí)符 (URI) 與前端系統(tǒng)(Android/iOS、HTML5/JavaScript)進(jìn)行溝通。
舉一個(gè)例子來說明單體服務(wù)和微服務(wù)的區(qū)別。
???
單體架構(gòu)類似于希臘的石頭雕像,而微服務(wù)類似樂高積木。石雕的某個(gè)部分損壞,必須報(bào)廢整個(gè)雕像,對(duì)其進(jìn)行重造。而樂高積木只需要更換部分組件即可。
顯而易見微服務(wù)在架構(gòu)復(fù)雜系統(tǒng)時(shí),是具備優(yōu)勢的,但是在落地過程中需要平衡速度和安全性。眾所周知微服務(wù)在 DevOps 領(lǐng)域以及持續(xù)開發(fā)持續(xù)集成(CD/CI)方面可以提高應(yīng)用開發(fā)和交付的速度,特別適用于復(fù)雜業(yè)務(wù)場景,并且提升交付速度。
但是由于微服務(wù)的服務(wù)獨(dú)立和分散的特點(diǎn),我們還需要關(guān)注每個(gè)服務(wù)的安全性問題,因此在微服務(wù)架構(gòu)的設(shè)計(jì)和實(shí)施方案中需要考慮通過統(tǒng)一的服務(wù)編寫或者實(shí)施標(biāo)準(zhǔn)來規(guī)避安全風(fēng)險(xiǎn),這里建議創(chuàng)建“central key deliverable”(中心關(guān)鍵交付原則 / 標(biāo)準(zhǔn)),所有服務(wù)都圍繞這個(gè)標(biāo)準(zhǔn)進(jìn)行設(shè)計(jì),避免各個(gè)服務(wù)各自為政。
微服務(wù)實(shí)施模型
???
第 1 階段:專注于敏捷性和響應(yīng)性
在線流媒體服務(wù) Netflix 以提供點(diǎn)播服務(wù)而著稱,它為用戶提供了優(yōu)質(zhì)的 USP 體驗(yàn)。微服務(wù)的架構(gòu)使得交付周期大幅縮短,開發(fā)頻率提高,同時(shí)還提供持續(xù)的服務(wù)交付。
針對(duì)應(yīng)用的特性而言,每個(gè)應(yīng)用所需要的資源量并不是相等的。有些應(yīng)用可能比其他應(yīng)用被使用的頻率更高,因此需要更多的資源作為支撐。以核心業(yè)務(wù)能力作為架構(gòu)的中心,其他服務(wù)作為核心能力的擴(kuò)充。比如視頻播放就是核心業(yè)務(wù),會(huì)員點(diǎn)播、訂閱、積分等等就需要圍繞這個(gè)核心業(yè)務(wù)展開,這些圍繞核心業(yè)務(wù)的服務(wù)可以以微服務(wù)的形式存在,但需要與核心業(yè)務(wù)建立良好的調(diào)用接口和通訊模式。
因此可以講核心服務(wù)與企業(yè)服務(wù)從以下兩個(gè)層面進(jìn)行定義:
功能層面的擴(kuò)展:圍繞核心服務(wù)的其他服務(wù)作為應(yīng)用功能的擴(kuò)展,對(duì)于 Netflix 而言核心服務(wù)無疑是視頻的播放,而其他的周邊服務(wù)會(huì)根據(jù)用戶需求的增加或者改變進(jìn)行調(diào)整。這種根據(jù)業(yè)務(wù)和用戶需求擴(kuò)展的服務(wù)就需要能夠自由擴(kuò)展,同時(shí)也不會(huì)影響核心服務(wù),這里就需要使用到微服務(wù)的敏捷性特征,定義好擴(kuò)展服務(wù)與核心服務(wù)的接口和協(xié)議以后,就可以針對(duì)用戶需求對(duì)服務(wù)進(jìn)行擴(kuò)展。
資源能力的擴(kuò)展:如果說功能層面的擴(kuò)展和業(yè)務(wù)掛鉤,資源能力的擴(kuò)展就是和流量掛鉤。由于 Netflix 本質(zhì)還是資源 / 服務(wù)的提供者,而消費(fèi)資源 / 服務(wù)的用戶的數(shù)量并不是一定的,如何做到資源的伸縮是 Netflix 需要考慮的問題。在真實(shí)業(yè)務(wù)場景中,用戶的訪問量或者說網(wǎng)站的流量是波動(dòng)的,那么 Netflix 網(wǎng)站提供的資源也應(yīng)該隨著用戶的訪問量的變化而及時(shí)調(diào)整。在微服務(wù)架構(gòu)中就可以靈活地調(diào)整這種資源的分配,Netflix 就是針對(duì) 5 個(gè)用戶使用資源作為步長進(jìn)行資源擴(kuò)展或者收縮,實(shí)際上在很多計(jì)算機(jī)技術(shù)中也會(huì)利用類似的思路解決資源的不確定性。例如 MySQL 中的 VARCHAR 類型也是通過變長的方式擴(kuò)展字符的存儲(chǔ)空間的。
第 2 階段:管理安全性和源代碼成熟度統(tǒng)一
盡管采用微服務(wù)架構(gòu)每個(gè)服務(wù)都可以使用不同技術(shù)棧完成不同的業(yè)務(wù)功能,但畢竟所有的服務(wù)都是為了完成一個(gè)商業(yè)目的,同時(shí)存在于一個(gè)系統(tǒng)中。因此在微服務(wù)的實(shí)施過程中注重每個(gè)單獨(dú)服務(wù)的安全性管理,以貨幣交易系統(tǒng)為例,如果采用微服務(wù)的架構(gòu),那么其中的轉(zhuǎn)賬服務(wù)、工資發(fā)放服務(wù)、零售交易服務(wù)都需要遵從相同的安全級(jí)別。
這個(gè)在微服務(wù)實(shí)施過程中尤為重要,也是在考驗(yàn)微服務(wù)架構(gòu)安全管理的能力。換句話說就是針對(duì)微服務(wù)定義安全準(zhǔn)則包括數(shù)據(jù)安全性、通訊安全性、訪問安全性。甚至提供通用的微服務(wù)包裝這些安全規(guī)則,其他的服務(wù)只需要調(diào)用對(duì)應(yīng)的標(biāo)準(zhǔn)服務(wù)或者組件即可,這樣即便是使用不同技術(shù)棧的服務(wù)也能遵循同樣的安全標(biāo)準(zhǔn)。
除了安全標(biāo)準(zhǔn),微服務(wù)還需要對(duì)代碼成熟度進(jìn)行管理,需要標(biāo)準(zhǔn)化每個(gè)服務(wù)源代碼的成熟度級(jí)別,以在服務(wù)提供階段提供特定目標(biāo)和解決方案。但是如果針對(duì)每個(gè)服務(wù)源代碼去定義成熟級(jí)別,顯然無法做到架構(gòu)層面的統(tǒng)一,而且在微服務(wù)的開發(fā)過程中會(huì)有多個(gè)團(tuán)隊(duì)共同參與,代碼有可能會(huì)被多個(gè)繼任團(tuán)隊(duì)維護(hù),因此需要從整個(gè)系統(tǒng)的高度去定義代碼成熟度的級(jí)別。
不這樣做,服務(wù)內(nèi)部不僅不能應(yīng)對(duì)復(fù)雜的業(yè)務(wù)變化,也無法與整體架構(gòu)統(tǒng)一做到目標(biāo)(速度 / 安全性)與系統(tǒng)的可擴(kuò)展。因此,單個(gè)服務(wù)的源代碼變更需要與系統(tǒng)整體源代碼的成熟度保持一致,從而降低兩者缺乏同步的長期風(fēng)險(xiǎn)。簡單來說就是單個(gè)微服務(wù)以及整體架構(gòu)的代碼成熟度需要保持一致。
眾所周知一個(gè)軟件的非功能性需求包括:高性能、可用性、擴(kuò)展性、伸縮性、安全性。每個(gè)維度都可以定義成熟度的指標(biāo)和級(jí)別。例如軟件安全的成熟度模型中就會(huì)從監(jiān)管、構(gòu)造、確認(rèn)、部署等四個(gè)方面進(jìn)行定義。每個(gè)類別又會(huì)分三個(gè)等級(jí)來定義成熟度的級(jí)別,這里不展開說明。
第 3 階段:確保解決方案和系統(tǒng)運(yùn)營的可擴(kuò)展性
系統(tǒng)實(shí)施之后的返工成本非常高,因此系統(tǒng)設(shè)計(jì)初期就需要考慮業(yè)務(wù)擴(kuò)展以及訪問存儲(chǔ)量的增加,總的來說是要未雨綢繆。特別是在業(yè)務(wù)場景復(fù)雜、商業(yè)環(huán)境多變的當(dāng)下,應(yīng)用架構(gòu)的擴(kuò)展和伸縮需要和業(yè)務(wù)發(fā)展以及收入保持匹配,避免兩者出現(xiàn)不一致的情況。例如業(yè)務(wù)量增長了,系統(tǒng)無法承載高訪問量,又或者業(yè)務(wù)拓展以后在原有核心功能上增加了其他功能,而系統(tǒng)架構(gòu)對(duì)于功能擴(kuò)展反映緩慢,又或許無法擴(kuò)展。
其中需要注意的是,系統(tǒng)的解決方案需要符合業(yè)務(wù)的擴(kuò)展、向外能夠兼容第三方軟件、隨著業(yè)務(wù)增加重新部署周期保持在平均水平、系統(tǒng)的訪問量波動(dòng)和運(yùn)營成本保持一致。
另一個(gè)需要注意的是系統(tǒng)功能層面需要有長遠(yuǎn)考慮,降低系統(tǒng)的復(fù)雜性水平,避免后續(xù)功能的引入對(duì)系統(tǒng)的影響。例如在系統(tǒng)設(shè)計(jì)初期可以根據(jù)實(shí)際業(yè)務(wù)進(jìn)行接口設(shè)計(jì),而針對(duì)當(dāng)時(shí)的情況進(jìn)行業(yè)務(wù)實(shí)現(xiàn),這樣可以應(yīng)對(duì)業(yè)務(wù)的變化。
例如創(chuàng)建一個(gè)中間平臺(tái),為卡車服務(wù)和客戶之間充當(dāng)中介者的角色,那么就要考慮到接入不同的卡車服務(wù)包括:個(gè)人卡車用戶、集體卡車用戶、以及平臺(tái)。同時(shí)也要考慮結(jié)算服務(wù),針對(duì)不同的結(jié)算方式(微信、支付寶、網(wǎng)銀),又或者針對(duì)同一種支付方式的不同支付實(shí)體(例如:網(wǎng)銀包括:工商銀行、建設(shè)銀行、招商銀行等)建立對(duì)應(yīng)的接口,所有的服務(wù)是面向接口進(jìn)行編程,一旦實(shí)現(xiàn)的對(duì)象例如支付實(shí)體從微信切換成了支付寶,又例如網(wǎng)銀實(shí)體從工商銀行切換成了招商銀行,只需要用新的服務(wù)實(shí)現(xiàn)替換就可以了,服務(wù)之間的接口并不需要進(jìn)行調(diào)整。而接口的定義恰恰是在架構(gòu)設(shè)計(jì)階段是可以預(yù)見的。
第 4 階段:保證單個(gè)服務(wù)的獨(dú)立性和完整性 - 服務(wù)即解決方案
整個(gè)微服務(wù)架構(gòu)就是多個(gè)獨(dú)立服務(wù)組成的,每個(gè)服務(wù)就是一個(gè)獨(dú)立的解決方案,單個(gè)服務(wù)盡量不對(duì)其他服務(wù)進(jìn)行依賴,如果是依賴也是對(duì)接口進(jìn)行依賴。這樣的設(shè)計(jì)就好像樂高積木一樣,每個(gè)服務(wù)各司其職,也很容易被替換和擴(kuò)展。
針對(duì)每個(gè)服務(wù)定義規(guī)范的功能描述和輸入輸出參數(shù),以及消息傳送格式,并且將這些信息在系統(tǒng)內(nèi)部公開,讓其他服務(wù)知道該服務(wù)所完成的功能和服務(wù)邊界是什么。這種方式讓服務(wù)與服務(wù)之間能夠做到無縫對(duì)接,也避免了重復(fù)造輪子的尷尬,同時(shí)也為數(shù)據(jù)中臺(tái)、服務(wù)中臺(tái)打下了基礎(chǔ)。
在 Walmart Labs 的案例中,系統(tǒng)架構(gòu)每月進(jìn)行多達(dá) 30,000 次更新,而這些更新是由 3000 名工程師使用 OneOps 平臺(tái)完成的。由于將服務(wù)的云化,提高了開發(fā)效率降低了開發(fā)新業(yè)務(wù)的難度,提升了組織在不同領(lǐng)域的競爭力。
也就是說公司面對(duì)復(fù)雜環(huán)境時(shí)可以利用哪些不變的服務(wù)組件(顆粒度足夠小)以及公司對(duì)市場以及業(yè)務(wù)的理解,通過組合、集成、擴(kuò)展的方式快速高效地搭建新的應(yīng)用程序,從而快速適合新的業(yè)務(wù)模式,服務(wù)客戶占領(lǐng)市場。
第 5 階段:善用流程、 工具和組織結(jié)構(gòu)
公司需要明白,想讓微服務(wù)成功落地就需要對(duì)系統(tǒng)構(gòu)建過程進(jìn)行改革,不同于傳統(tǒng)單體應(yīng)用的層級(jí)開發(fā)模型。開發(fā)者工作在不同的層級(jí)上,前端、后端、H5 ,甚至在后端中還可以劃分為面向數(shù)據(jù)庫以及面向業(yè)務(wù)的開發(fā)。這種方式在微服務(wù)環(huán)境中已經(jīng)不適用,必須要開發(fā)人員知道自己就是微服務(wù)的主人,你開發(fā)的微服務(wù)就是代表你的產(chǎn)品,它會(huì)被系統(tǒng)中其他的服務(wù)消費(fèi),也就是說其他服務(wù)就是你的客戶。所以,你必須成為唯一對(duì)該服務(wù)負(fù)責(zé)的人,只要和這個(gè)服務(wù)相關(guān)的一切都需要關(guān)注,這就迫使開發(fā)人員成為全棧工程師,對(duì)人、對(duì)組織、對(duì)開發(fā)流程都是較高的要求。
微服務(wù)的開發(fā)者需要把服務(wù)當(dāng)作產(chǎn)品一樣管理,包括設(shè)計(jì)、編碼、UI 開發(fā)、同時(shí)還要保證質(zhì)量交付和以及運(yùn)維過程中的故障排除和調(diào)試升級(jí)。
看上去開發(fā)者的責(zé)任變大了,不過有一些 DevOps 工具通過持續(xù)集成和交付的方式協(xié)助微服務(wù)的開發(fā),從而確保單點(diǎn)故障 (SPOF) 不會(huì)影響其他服務(wù)。同時(shí)也引入了容器化的部署方式,Docker 的部署方式就是很明顯的例子。Docker 的部署只針對(duì)單個(gè)服務(wù)的范圍,提高了標(biāo)準(zhǔn)化以及利用容器映像 (CI Continued Integration 持續(xù)集成) 的效率。比起傳統(tǒng)方式的整體發(fā)布來說,無論對(duì)發(fā)布成本和試錯(cuò)成本來說,容器化的部署工具都是性價(jià)比最高的選擇。
第 6 階段:整體系統(tǒng)實(shí)施策略
微服務(wù)架構(gòu)是近幾年隨著業(yè)務(wù)發(fā)展興起的,站在整體系統(tǒng)的角度如何落地微服務(wù)架構(gòu)一直是架構(gòu)師面臨的問題。新的系統(tǒng)可以完全重新開始,但是對(duì)于遺留系統(tǒng)而言要實(shí)施微服務(wù)架構(gòu)不是一件容易的事情。
這里提供了三種策略給大家參考,如圖所示:
第一種 Cream Scoop Strategy 冰淇淋勺策略:是 Martin Flower 提出的一種策略,也被稱為扼殺者方法??梢韵胂笥幸淮笸氨苛?,這桶冰淇淋就代表現(xiàn)有的架構(gòu),可以用勺子從桶中挖出你們想要的冰淇淋,這個(gè)挖出的部分就是要做拆分的服務(wù)。最終可以將大桶冰淇淋挖出一個(gè)個(gè)獨(dú)立的服務(wù),這里服務(wù)包含不同的業(yè)務(wù)邏輯。這種方式是逐漸修改原有系統(tǒng),并且逐步對(duì)服務(wù)進(jìn)行拆分試錯(cuò)然后過度到單獨(dú)的資源上運(yùn)行。每次拆分對(duì)系統(tǒng)的影響較小,但是整個(gè)系統(tǒng)的拆分和重構(gòu)需要較長時(shí)間。
第二種 樂高法策略(搭積木),把原有的系統(tǒng)想象成一大塊樂高積木,我們只需要往上面添加小的樂高積木模塊就行了,添加的小模塊就是一個(gè)個(gè)微服務(wù)。這樣一來就不用對(duì)老產(chǎn)品進(jìn)行調(diào)整,新的功能通過微服務(wù)的方式實(shí)現(xiàn)并且集成到老的產(chǎn)品中。不過需要通過一種能夠讓微服務(wù)與老產(chǎn)品聯(lián)系的方法,這里會(huì)使用到接口編程以及適配器模式。
第三種是 nuclear 策略,和策略的名字一樣我們需要對(duì)老舊系統(tǒng)推到重來,重新打造微服務(wù)架構(gòu),說起來容易這里需要花費(fèi)大量分析和重構(gòu)的時(shí)間,這個(gè)周期比較長,成本也是較高的。
???
微服務(wù)架構(gòu)實(shí)施策略
第 7 階段:調(diào)整姿態(tài)直面轉(zhuǎn)型
在微服務(wù)架構(gòu)實(shí)施過程中,領(lǐng)導(dǎo)方式和公司文化都起著舉足輕重的作用,無論在何種情況下這兩點(diǎn)都是復(fù)雜、模糊且多變的因素。也就是沒有很好的建議和思路,只有見招拆招不斷適應(yīng)業(yè)務(wù)的變化調(diào)整組織能力和領(lǐng)導(dǎo)方向。不過有一點(diǎn)是可以肯定的,企業(yè)需要不斷觀察和分析市場的變化傾聽客戶的聲音,將變革的頻率與市場的波動(dòng)同步,打造自我學(xué)習(xí)不斷適應(yīng)的企業(yè)文化。領(lǐng)導(dǎo)方式需要在企業(yè)文化的基礎(chǔ)上,不斷對(duì)外來需求進(jìn)行評(píng)估,從而開闊視野,簡化最終結(jié)果不斷迭代,因?yàn)檎l也不能保證開發(fā)出完美的系統(tǒng)和產(chǎn)品。唯有適應(yīng)市場的變化,不斷提升自身能力,持續(xù)打磨系統(tǒng),才能立于不敗之地。以終為始,打造領(lǐng)導(dǎo)力,調(diào)整組織結(jié)構(gòu),創(chuàng)建公司文化,讓利益相關(guān)者信任并參與進(jìn)來,形成公司的核心競爭力。
總結(jié)
本文從業(yè)務(wù)發(fā)展說起,為了適應(yīng)復(fù)雜多變的業(yè)務(wù)場景,系統(tǒng)從單體架構(gòu)進(jìn)化到了微服務(wù)架構(gòu)。獨(dú)立服務(wù)、功能可擴(kuò)展性以及資源的伸縮性讓微服務(wù)架構(gòu)在紛繁復(fù)雜的商業(yè)環(huán)境中占領(lǐng)了一席之地。
但也正因?yàn)檫@些特性增加了微服務(wù)落地的復(fù)雜度,本文通過 7 個(gè)階段模型幫助企業(yè)落地微服務(wù)架構(gòu)。包括:
- 專注敏捷性和響應(yīng)性:功能和資源層面的擴(kuò)展;
- 安全性和源代碼成熟度:創(chuàng)建安全和成熟度標(biāo)準(zhǔn);
- 解決方案和系統(tǒng)運(yùn)營的可擴(kuò)展性;
- 服務(wù)的獨(dú)立性和完整性;
- 善用流程、工具和組織結(jié)構(gòu);
- 整體系統(tǒng)實(shí)施策略;
- 調(diào)整姿態(tài)直面轉(zhuǎn)型。
作者介紹
崔皓,51CTO 社區(qū)編輯,資深架構(gòu)師,擁有 18 年的軟件開發(fā)和架構(gòu)經(jīng)驗(yàn),10 年分布式架構(gòu)經(jīng)驗(yàn)。曾任惠普技術(shù)專家。樂于分享,撰寫了很多熱門技術(shù)文章,閱讀量超過 60 萬。??《分布式架構(gòu)原理與實(shí)踐》??作者。
【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請注明原文作者和出處為51CTO.com】
???