王健+李冬睿



摘 要 文章針對(duì)目前單一模式系統(tǒng)開(kāi)發(fā)周期周期長(zhǎng)、開(kāi)發(fā)成本高等困難,將原有系統(tǒng)往微服務(wù)架構(gòu)上遷移提出了幾種解決方案,結(jié)合具體場(chǎng)景,講述了各個(gè)環(huán)節(jié)的實(shí)現(xiàn)機(jī)制。
關(guān)鍵詞 微服務(wù) 單一模式 遷移轉(zhuǎn)化技術(shù)
中圖分類(lèi)號(hào):TP271.4 文獻(xiàn)標(biāo)識(shí)碼:A DOI:10.16400/j.cnki.kjdkx.2016.09.021
Abstract Aiming at the current development cycle of single mode system of long period, high cost of development difficulties, the original system to the micro service architecture on migration of several solutions are proposed, combined with the specific scene, describes the realization mechanism of each link.
Key words micro service; single mode; migration and transformation technology
1 Web系統(tǒng)架構(gòu)情況概述和分析
目前web系統(tǒng)架構(gòu)具有如下幾個(gè)特征:(1)以快速上線,快速迭代方式發(fā)布單一系統(tǒng)為主要模式。單一系統(tǒng)開(kāi)發(fā)易于調(diào)試,只需要簡(jiǎn)單運(yùn)行此應(yīng)用;易于部署,只需要把打包應(yīng)用拷貝到服務(wù)器端,通過(guò)在負(fù)載均衡器后端運(yùn)行多個(gè)拷貝無(wú)狀態(tài)服務(wù)就可以輕松實(shí)現(xiàn)應(yīng)用的橫行擴(kuò)展。對(duì)于中小型web系統(tǒng)開(kāi)發(fā)周期快,運(yùn)維門(mén)檻低。(2)隨著需求變更,系統(tǒng)逐漸演變的越來(lái)越復(fù)制。最主要問(wèn)題就是這個(gè)應(yīng)用太復(fù)雜,以至于任何單個(gè)開(kāi)發(fā)者都不可能搞懂它。因此,修正bug和正確的添加新功能變的非常困難,并且很耗時(shí)。另外,如果代碼難于理解,就不可能被正確的修改。最終會(huì)走向巨大的、不可理解的泥潭。(3)傳統(tǒng)開(kāi)發(fā)模式無(wú)成本和效率優(yōu)勢(shì),制約企業(yè)發(fā)展。目前單一架構(gòu)應(yīng)用也使得采用新架構(gòu)和語(yǔ)言非常困難。應(yīng)用無(wú)法擴(kuò)展,可靠性很低,最終,敏捷開(kāi)發(fā)和快速部署變得無(wú)法完成。
2 微服務(wù)架構(gòu)處理復(fù)雜事務(wù)
2.1 微服務(wù)架構(gòu)優(yōu)勢(shì)
微服務(wù)架構(gòu)將服務(wù)拆分,分別采用相對(duì)獨(dú)立的服務(wù)對(duì)各方面進(jìn)行管理,彼此之間使用統(tǒng)一的接口來(lái)進(jìn)行交流,架構(gòu)變得復(fù)雜,優(yōu)勢(shì)也很明顯(如圖1)。
(1)解決了復(fù)雜性問(wèn)題。它把龐大的單一模塊應(yīng)用分解為一系列的服務(wù),同時(shí)保持總體功能不變。這個(gè)應(yīng)用被分解為多個(gè)可管理的分支或服務(wù),每一個(gè)服務(wù)都有良好定義的邊界,以遠(yuǎn)程過(guò)程調(diào)用(RPC)驅(qū)動(dòng)或信息驅(qū)動(dòng)的API的形式;微服務(wù)架構(gòu)模式單一模塊代碼庫(kù),實(shí)際很難實(shí)現(xiàn)。因此,獨(dú)立的服務(wù)開(kāi)發(fā)速度明顯更快,而且更易理解和維護(hù)。
(2)讓每個(gè)服務(wù)能夠獨(dú)立開(kāi)發(fā),開(kāi)發(fā)者能夠自由選擇可行的技術(shù),讓服務(wù)來(lái)決定API約定。當(dāng)然,大多數(shù)組織會(huì)通過(guò)限制技術(shù)選擇來(lái)避免完全的失控。然而,這種自由意味著開(kāi)發(fā)者們不用被迫使用從項(xiàng)目開(kāi)始就存在的陳舊技術(shù),他們可以選擇使用當(dāng)下的技術(shù)編寫(xiě)一個(gè)新的服務(wù)。另外,由于這些服務(wù)本身相對(duì)比較小,用新的技術(shù)來(lái)重寫(xiě)舊的服務(wù)也更可行一些。
(3)每個(gè)微服務(wù)都能獨(dú)立配置,開(kāi)發(fā)者不必協(xié)調(diào)對(duì)于本地服務(wù)配置上的變化,這種變化一旦測(cè)試完成就被配置了。舉個(gè)例子,UI團(tuán)隊(duì)可以執(zhí)行A|B測(cè)試后立刻對(duì)UI的變化執(zhí)行迭代。微服務(wù)架構(gòu)模式使不斷地配置成為可能。
(4)讓每個(gè)服務(wù)都可以獨(dú)立調(diào)整,你可以給每個(gè)服務(wù)配置正好滿足容量和可用性限制的實(shí)例數(shù)。另外,你也可以使用最適合服務(wù)的資源需求的硬件。舉例說(shuō)明,你可以在EC2計(jì)算優(yōu)化的實(shí)例上配置CPU加強(qiáng)的圖片處理服務(wù),另外給EC2存儲(chǔ)優(yōu)化的實(shí)例配置內(nèi)存中的數(shù)據(jù)庫(kù)服務(wù)。
2.2 實(shí)踐從單一模式系統(tǒng)重構(gòu)到微服務(wù)架構(gòu)系統(tǒng)
為了未來(lái)系統(tǒng)的擴(kuò)展性,對(duì)原有龐大的單一模式系統(tǒng)進(jìn)行微服務(wù)重構(gòu),既讓人興奮,又充滿挑戰(zhàn),下文將提到幾種重構(gòu)方案。這里需要強(qiáng)調(diào)下按照微服務(wù)架構(gòu),重寫(xiě)全部系統(tǒng)代碼,對(duì)任何已經(jīng)在線上運(yùn)行的中大型web系統(tǒng)來(lái)說(shuō),都是不可行的,變更風(fēng)險(xiǎn)太大,系統(tǒng)測(cè)試不完善會(huì)直接導(dǎo)致,系統(tǒng)擋掉,無(wú)法對(duì)外提供服務(wù)。
2.2.1 停止在單一模式的系統(tǒng)上開(kāi)發(fā)新業(yè)務(wù)
首先停止讓問(wèn)題更糟。不要繼續(xù)通過(guò)向單一應(yīng)用程序添加代碼的方式來(lái)實(shí)現(xiàn)新功能。采用某種方式來(lái)將新功能實(shí)現(xiàn)為獨(dú)立的服務(wù)。這可能并不容易。你可能會(huì)編寫(xiě)凌亂的,復(fù)雜的膠水代碼來(lái)向單塊應(yīng)用程序集成服務(wù)。但這是打散單塊程序的第一步。
這種方案有2個(gè)新增模塊“request router”和“glue code”(如圖2):
Request Router
前端的請(qǐng)求路由層,用于處理(HTTP)請(qǐng)求,將符合新規(guī)則的請(qǐng)求發(fā)送給新增的服務(wù),老的請(qǐng)求發(fā)給原有系統(tǒng)。
GlueCode
在程序設(shè)計(jì)中,為了讓新服務(wù)可以使用老系統(tǒng)的功能和數(shù)據(jù)設(shè)計(jì)編寫(xiě)的,將不同部分的不兼容的代碼“粘合在一起”。在編寫(xiě)代碼過(guò)程中,粘合代碼為了讓存在的庫(kù)或程序間進(jìn)行交互。這里有3種訪問(wèn)老系統(tǒng)方案:
(1)給單一系統(tǒng)添加遠(yuǎn)程調(diào)用API
可以使用REST HTTP API
或者跨語(yǔ)言調(diào)用框架 Thrift RPC;
(2)直接訪問(wèn)單一系統(tǒng)數(shù)據(jù)庫(kù);
(3)訪問(wèn)復(fù)制的同步的單一系統(tǒng)數(shù)據(jù)庫(kù),并保持同步。
利用以往的開(kāi)發(fā)經(jīng)驗(yàn),可以新建一個(gè)可伸縮的微服務(wù),控制住單一系統(tǒng)的復(fù)雜度。
2.2.2抽離web層與業(yè)務(wù)邏輯層
表現(xiàn)層與業(yè)務(wù)邏輯層分離。單一模式系統(tǒng)內(nèi)的架構(gòu)中,調(diào)整本地調(diào)用方法,更改為遠(yuǎn)程調(diào)用方法。
典型Web應(yīng)用通常由至少三個(gè)不同類(lèi)型的部分組成(如圖3):
表示層——處理HTTP請(qǐng)求并實(shí)現(xiàn)(REST)API或基于HTML的網(wǎng)頁(yè)UI的組件。在一個(gè)有復(fù)雜的用戶界面的應(yīng)用中,表達(dá)層常常有大量的代碼段。
業(yè)務(wù)邏輯層——是應(yīng)用的核心組件,實(shí)現(xiàn)業(yè)務(wù)規(guī)則。
數(shù)據(jù)訪問(wèn)層——訪問(wèn)基礎(chǔ)設(shè)施組件的組件,比如數(shù)據(jù)庫(kù)和消息代理。
抽離展現(xiàn)層的優(yōu)點(diǎn):
(1)接口預(yù)先定義,開(kāi)發(fā)視野提升,需求驅(qū)動(dòng)。
(2)開(kāi)發(fā)和設(shè)計(jì)工作分離。
(3)利于更快定位性能瓶頸。
3 總結(jié)
單一模式是構(gòu)建企業(yè)級(jí)應(yīng)用程序常用的模式。對(duì)于小的應(yīng)用程序它很適用:開(kāi)發(fā),測(cè)試和部署小型的單塊程序相對(duì)簡(jiǎn)單。但是,對(duì)于大型的復(fù)雜的應(yīng)用程序,單一模式會(huì)阻礙開(kāi)發(fā)和部署。如果你經(jīng)常長(zhǎng)期的鎖定你的初始技術(shù)選擇,則會(huì)使得持續(xù)交付變得困難。對(duì)于大型的應(yīng)用程序,更適合適用微服務(wù)架構(gòu),其將應(yīng)用程序分解為一組服務(wù)。
微服務(wù)架構(gòu)有很多優(yōu)點(diǎn)。例如,單個(gè)服務(wù)更容易理解,可以獨(dú)立于其它服務(wù)來(lái)開(kāi)發(fā)和部署。也更容易使用新的語(yǔ)言和技術(shù),因?yàn)槟憧梢砸淮沃粚?duì)一個(gè)服務(wù)嘗試新技術(shù)。微服務(wù)架構(gòu)也有一些顯著的缺點(diǎn)。特別是對(duì)那些更復(fù)雜,擁有更多變化部分的應(yīng)用程序。你需要高級(jí)別的自動(dòng)化,來(lái)高效地使用微服務(wù)。你也需要在開(kāi)發(fā)微服務(wù)時(shí)處理一些復(fù)雜的分布式數(shù)據(jù)管理問(wèn)題。盡管有這些缺點(diǎn),微服務(wù)架構(gòu)還是更適用于大型的復(fù)雜的應(yīng)用程序,因?yàn)榭梢钥焖傺莼?/p>
參考文獻(xiàn)
[1] 韋伯.帕拉斯泰迪斯.魯濱遜.REST實(shí)戰(zhàn):中文版超媒體和系統(tǒng)架構(gòu).中國(guó):東南大學(xué)出版社,2011.
[2] MICROSERVICES From Design to Deployment by Chris Richardson with Floyd Smith.
[3] Building Micorservices by Sam Newman Copyright 2015 Published by OReilly Media.