原文如下:http://martinfowler.com/articles/microservices.html
微服務(wù)###
一個新的架構(gòu)術(shù)語
“微服務(wù)架構(gòu)”一詞是在過去幾年里涌現(xiàn)出來的存皂,它用于描述一種獨立部署的軟件應(yīng)用設(shè)計方式伦意。這種架構(gòu)方式并沒有非常明確的定義煞烫,但有一些共同的特點就是圍繞在業(yè)務(wù)能力、自動化布署、端到端的整合以及語言和數(shù)據(jù)的分散控制上面躯畴。
“微服務(wù)”- 這是在軟件架構(gòu)領(lǐng)域這個非常擁擠的街道上国旷,冒出的一個新名詞而已。雖然我們對這個新出的名詞不屑一顧屉来,但是它所描述的軟件系統(tǒng)的風(fēng)格越來越吸引我們的注意力路翻。在過去的幾年里,我們發(fā)現(xiàn)越來越多的項目開始使用這個風(fēng)格茄靠,并且到目前為止得到的反饋都是積極的茂契,以至于我身邊的許多同事在設(shè)計企業(yè)架構(gòu)時,都把它作為默認的構(gòu)建方式慨绳,然而很不幸掉冶,到底什么是微服務(wù),我們又如何來使用它脐雪,外界并沒有太多的信息可供參考厌小。
總之,微服務(wù)這種架構(gòu)風(fēng)格就是把一組小服務(wù)演化成為一個單一的應(yīng)用的一種方法战秋。每個應(yīng)用都運行在自己的進程中璧亚,并通過輕量級的機制保持通信,就像HTTP這樣的API脂信。這些服務(wù)要基于業(yè)務(wù)場景癣蟋,并使用自動化布署工具進行獨立的發(fā)布≌粒可以有一個非常輕量級的集中式管理來協(xié)調(diào)這些服務(wù)疯搅,可以使用不同的語言來編寫服務(wù),也可以使用不同的數(shù)據(jù)存儲埋泵。
在開始解釋什么是微服務(wù)之前幔欧,先介紹一下單體應(yīng)用還是很有用的:把一個單體應(yīng)用構(gòu)建成為一個部分。企業(yè)應(yīng)用通過是由三個重要部分組成:客戶端界面(由HTML秋泄、Javascript組成琐馆,使用瀏覽器進行訪問)、數(shù)據(jù)庫(由許多的表組件構(gòu)成一個通用的恒序、相互關(guān)聯(lián)的數(shù)據(jù)管理系統(tǒng))瘦麸、服務(wù)端應(yīng)用。服務(wù)端應(yīng)用處理HTTP請求歧胁、執(zhí)行領(lǐng)域邏輯滋饲、檢索并更新數(shù)據(jù)庫中的數(shù)據(jù)厉碟、選擇和填充HTML視圖發(fā)送給客戶端。這個服務(wù)端應(yīng)用是一個單塊結(jié)構(gòu)也就是一個整體屠缭,這是一個可執(zhí)行的單一邏輯箍鼓,系統(tǒng)中的任何修改都將導(dǎo)致服務(wù)端應(yīng)用重新編譯和布署一個新版本。
就這樣一個單體應(yīng)用很自然的被構(gòu)建成了一個系統(tǒng)呵曹,雖然可以使用開發(fā)語言基本特性會把應(yīng)用封裝成類款咖、函數(shù)、命名空間奄喂,但是業(yè)務(wù)中所有請求都要在單一的進程中處理完成铐殃,在某些場景中,你可以在開發(fā)人員的筆記本電腦中運行和測試跨新,并且通過布署通道將測試通過的程序布署到生產(chǎn)環(huán)境中富腊,你還可以水平擴展,利用負載均衡將實例布署到多臺服務(wù)器中域帐。
的確赘被,單體應(yīng)用也是很成功的,但是越來越多的人感覺到了不妥肖揣,特別是應(yīng)用程序被發(fā)布到了云的時候民假,變更發(fā)布周期被綁定了 —- 原來可以劃分成小的應(yīng)用、小的需要的變更许饿,需要統(tǒng)一的進行編譯和發(fā)布阳欲。隨著時間的推移,軟件開發(fā)者很難保持原有好的模塊架構(gòu)陋率,使得一個模塊的變更很難不會影響到其它的模塊,而且在擴展方面也只能進行整體的擴展秽晚,而不能根據(jù)進行部分的擴展瓦糟。
這些原因?qū)е铝宋⒎?wù)架構(gòu)風(fēng)格的出現(xiàn):以服務(wù)構(gòu)建應(yīng)用。這些服務(wù)還可以被獨立布署赴蝇、獨立擴展菩浙,每個服務(wù)也都提供了清晰的模塊邊界,甚至不同的服務(wù)都可以使用不同的編程語言來實現(xiàn)句伶,也可以由不同的團隊進行管理劲蜻。
微服務(wù)的概念不是我們發(fā)明的,它至少起源于Unix時代的設(shè)計原則考余,我們認為這種風(fēng)格所帶來的好處先嬉,并沒有引起足夠多人的重視。
微服務(wù)架構(gòu)特征
我們沒有辦法對微服務(wù)有一個正式的定義楚堤,但我們可以嘗試表述適合這種架構(gòu)的共同特征來給它打上特性標簽疫蔓,共同特性并不代表每個服務(wù)都具備這些特點含懊,但是我們真的期望大多數(shù)微服務(wù)架構(gòu)能具備其中大部分特點。雖然我們的作者已經(jīng)是松散社區(qū)的核心成員衅胀,但是我們也在嘗試描述我們工作中或者我們了解的組件中所理解的微服務(wù)岔乔。我們并不依賴于那些已經(jīng)明確過的定義。
組件化與服務(wù)
只要我們一直在從事軟件行業(yè)滚躯,我們的愿望就是雏门,軟件由很多組件組裝在一起,如同物理現(xiàn)實世界中類似的構(gòu)造方式掸掏。在過去的幾十年里剿配,我們已經(jīng)看到了大部分語言平臺公共庫有了長足的進步。
當(dāng)我們在談?wù)摻M件時阅束,我們遇到了組件定義方面的困難呼胚,我們給定的定義是:一個組件是軟件中的一個部分,可以獨立的替換和升級息裸。
微服務(wù)也會使用組件庫蝇更,將一個軟件組件化的主要方式就是將其分解成服務(wù),我們定義的庫是可以連接到程序并使用內(nèi)存函數(shù)的的組件庫呼盆,服務(wù)是進程外的組件年扩,如Web請求服務(wù)或者遠程調(diào)用來相互通信的組件。(這種定義的方式與其它面向?qū)ο蟪绦蛑蟹?wù)對象的概念是不一樣的)
把服務(wù)當(dāng)成組件(而不是組件庫)的一個原因是服務(wù)可以獨立布署访圃,如果你有一個應(yīng)用是由多個庫組成并且運行在一個進程中厨幻,那么任何一點的改變都會引起整個應(yīng)用的重新發(fā)布,但是將這個應(yīng)用拆解為多個服務(wù)腿时,你可以期待每個服務(wù)的變更僅需要發(fā)布相應(yīng)的服務(wù)就可以况脆,當(dāng)然這也不是絕對的,比如導(dǎo)致服務(wù)接口變更的更新就需要相應(yīng)服務(wù)的變化批糟,但是良好的架構(gòu)設(shè)計是通過聚合服務(wù)邊界并且按照合約實現(xiàn)服務(wù)演化格了,最大限度地減少因為改變影響其他地方。
把服務(wù)當(dāng)成組件的另一個考慮是這會擁有更加清晰的接口徽鼎,大多數(shù)的語言并沒有一個很好的機制來定義一個明確顯式的發(fā)布接口盛末,通常只有文檔和規(guī)范說明,讓用戶避免組件間過度緊密而導(dǎo)致高耦合否淤,通過顯示的遠程調(diào)用機制悄但,可以避免這種情況。
使用服務(wù)也有其自身的缺點石抡,遠程調(diào)用比進程內(nèi)部調(diào)用更加消耗性能檐嚣,而且遠程的API往往是粗粒度的,用起來不是很友好汁雷,對組件的職責(zé)進行變更净嘀,也會影響到進程間的交互报咳,那么操作起來也比較困難。
第一個可能性挖藏,我們看到每個服務(wù)是運行在獨立的進程上的暑刃。注意,這只是第一個可能性膜眠。服務(wù)也可以由多個進程組成岩臣,它們是同時開發(fā)和部署的,如果一個應(yīng)用進程和一個僅由該服務(wù)使用的數(shù)據(jù)庫宵膨。
圍繞業(yè)務(wù)能力進行組織
當(dāng)我們把一個大的應(yīng)用拆分成小的部分時架谎,我們的注意力主要集中在技術(shù)層面,拆分成UI團隊辟躏、服務(wù)端的邏輯團隊和數(shù)據(jù)庫團隊谷扣。當(dāng)使用這種標準對團隊進行劃分時,甚至一個非常小的更變都將導(dǎo)致跨團隊間項目協(xié)作捎琐,從而消耗時間和預(yù)算審批会涎。一個高效的團隊會針對這種情況進行改善,關(guān)注它們所涉及的應(yīng)用邏輯瑞凑,并從中做出較好的選擇末秃。換句話說,邏輯無處不在籽御×纺剑康威定律就是一個例子。
一個組織的溝通結(jié)構(gòu)反映了其設(shè)計的系統(tǒng)的結(jié)構(gòu)
-- Melvyn Conway, 1967
微服務(wù)的劃分方法有所不同技掏,它更傾向于圍繞業(yè)務(wù)功能對服務(wù)結(jié)構(gòu)進行劃分铃将、拆解,這些服務(wù)可以采用不同的技術(shù)棧來實現(xiàn)零截,包括用戶界面麸塞,持久層存儲,或任何對外協(xié)作涧衙,因此團隊?wèi)?yīng)該是跨職能的,包括開發(fā)所需要的全部技術(shù):用戶體驗奥此、數(shù)據(jù)庫和項目管理弧哎。
按照這種方式組織的公司是 www.comparethemarket.com,跨職能團隊負責(zé)建立和操作每個產(chǎn)品并且每個產(chǎn)品都被分成若干單獨的服務(wù)通過消息進行通信稚虎。
大型的單體應(yīng)用也可以按照業(yè)務(wù)功能進行模塊化的撤嫩,盡管這種例子不常見。當(dāng)然蠢终,我們也會敦促一個大型團隊在構(gòu)建一個單體應(yīng)用時按照業(yè)務(wù)線來進行劃分序攘,我們能看到主要問題在于茴她,這種組件形式會導(dǎo)致很多的上下文依賴,如果這個系統(tǒng)跨越很多模塊邊界程奠,對于一個單獨團隊是很難在短時間解決問題的丈牢。此外,我們發(fā)現(xiàn)模塊化方式需要大量的規(guī)范去強制執(zhí)行瞄沙,而服務(wù)組件明確的劃分己沛,使得團隊間的邊界也變得清晰起來。
產(chǎn)品不是項目
大多數(shù)的開發(fā)工作是使用這樣一種模型:其目的是完成可以交付的軟件距境,軟件開發(fā)完成就交給了維護團隊申尼,該項目組也就解散了。
微服務(wù)的支持者建議避免這種模型垫桂,認為一個團隊?wèi)?yīng)該負責(zé)產(chǎn)品的整個生命周期师幕,一個很通用的概念就是Amazon’s的“you build, you run it”,它要求開發(fā)團隊對軟件產(chǎn)品的整個生命周期負責(zé)诬滩,這使得開發(fā)人員可以每天都關(guān)注產(chǎn)品的運行情況霹粥,而且也能夠與用戶保持緊密的聯(lián)系,做一些必要的支持工作碱呼。
產(chǎn)品方式開發(fā)意味著與業(yè)務(wù)能力緊緊捆綁在一起蒙挑,而不是將軟件看成是一系列完成的功能,他們會關(guān)注如何讓軟件幫助其用戶提升業(yè)務(wù)能力愚臀。
單體應(yīng)用也可以采用上述產(chǎn)品的理念忆蚀,但是更小粒度的服務(wù)可以更容易的創(chuàng)建開發(fā)者與用戶之間的關(guān)系。