原文如下:http://martinfowler.com/articles/microservices.html
微服務###
一個新的架構術語
“微服務架構”一詞是在過去幾年里涌現(xiàn)出來的,它用于描述一種獨立部署的軟件應用設計方式。這種架構方式并沒有非常明確的定義,但有一些共同的特點就是圍繞在業(yè)務能力、自動化布署、端到端的整合以及語言和數(shù)據(jù)的分散控制上面。
“微服務”- 這是在軟件架構領域這個非常擁擠的街道上,冒出的一個新名詞而已。雖然我們對這個新出的名詞不屑一顧,但是它所描述的軟件系統(tǒng)的風格越來越吸引我們的注意力。在過去的幾年里,我們發(fā)現(xiàn)越來越多的項目開始使用這個風格,并且到目前為止得到的反饋都是積極的,以至于我身邊的許多同事在設計企業(yè)架構時,都把它作為默認的構建方式,然而很不幸,到底什么是微服務,我們又如何來使用它,外界并沒有太多的信息可供參考。
總之,微服務這種架構風格就是把一組小服務演化成為一個單一的應用的一種方法。每個應用都運行在自己的進程中,并通過輕量級的機制保持通信,就像HTTP這樣的API。這些服務要基于業(yè)務場景,并使用自動化布署工具進行獨立的發(fā)布??梢杂幸粋€非常輕量級的集中式管理來協(xié)調這些服務,可以使用不同的語言來編寫服務,也可以使用不同的數(shù)據(jù)存儲。
在開始解釋什么是微服務之前,先介紹一下單體應用還是很有用的:把一個單體應用構建成為一個部分。企業(yè)應用通過是由三個重要部分組成:客戶端界面(由HTML、Javascript組成,使用瀏覽器進行訪問)、數(shù)據(jù)庫(由許多的表組件構成一個通用的、相互關聯(lián)的數(shù)據(jù)管理系統(tǒng))、服務端應用。服務端應用處理HTTP請求、執(zhí)行領域邏輯、檢索并更新數(shù)據(jù)庫中的數(shù)據(jù)、選擇和填充HTML視圖發(fā)送給客戶端。這個服務端應用是一個單塊結構也就是一個整體,這是一個可執(zhí)行的單一邏輯,系統(tǒng)中的任何修改都將導致服務端應用重新編譯和布署一個新版本。
就這樣一個單體應用很自然的被構建成了一個系統(tǒng),雖然可以使用開發(fā)語言基本特性會把應用封裝成類、函數(shù)、命名空間,但是業(yè)務中所有請求都要在單一的進程中處理完成,在某些場景中,你可以在開發(fā)人員的筆記本電腦中運行和測試,并且通過布署通道將測試通過的程序布署到生產(chǎn)環(huán)境中,你還可以水平擴展,利用負載均衡將實例布署到多臺服務器中。
的確,單體應用也是很成功的,但是越來越多的人感覺到了不妥,特別是應用程序被發(fā)布到了云的時候,變更發(fā)布周期被綁定了 —- 原來可以劃分成小的應用、小的需要的變更,需要統(tǒng)一的進行編譯和發(fā)布。隨著時間的推移,軟件開發(fā)者很難保持原有好的模塊架構,使得一個模塊的變更很難不會影響到其它的模塊,而且在擴展方面也只能進行整體的擴展,而不能根據(jù)進行部分的擴展。
這些原因導致了微服務架構風格的出現(xiàn):以服務構建應用。這些服務還可以被獨立布署、獨立擴展,每個服務也都提供了清晰的模塊邊界,甚至不同的服務都可以使用不同的編程語言來實現(xiàn),也可以由不同的團隊進行管理。
微服務的概念不是我們發(fā)明的,它至少起源于Unix時代的設計原則,我們認為這種風格所帶來的好處,并沒有引起足夠多人的重視。
微服務架構特征
我們沒有辦法對微服務有一個正式的定義,但我們可以嘗試表述適合這種架構的共同特征來給它打上特性標簽,共同特性并不代表每個服務都具備這些特點,但是我們真的期望大多數(shù)微服務架構能具備其中大部分特點。雖然我們的作者已經(jīng)是松散社區(qū)的核心成員,但是我們也在嘗試描述我們工作中或者我們了解的組件中所理解的微服務。我們并不依賴于那些已經(jīng)明確過的定義。
組件化與服務
只要我們一直在從事軟件行業(yè),我們的愿望就是,軟件由很多組件組裝在一起,如同物理現(xiàn)實世界中類似的構造方式。在過去的幾十年里,我們已經(jīng)看到了大部分語言平臺公共庫有了長足的進步。
當我們在談論組件時,我們遇到了組件定義方面的困難,我們給定的定義是:一個組件是軟件中的一個部分,可以獨立的替換和升級。
微服務也會使用組件庫,將一個軟件組件化的主要方式就是將其分解成服務,我們定義的庫是可以連接到程序并使用內存函數(shù)的的組件庫,服務是進程外的組件,如Web請求服務或者遠程調用來相互通信的組件。(這種定義的方式與其它面向對象程序中服務對象的概念是不一樣的)
把服務當成組件(而不是組件庫)的一個原因是服務可以獨立布署,如果你有一個應用是由多個庫組成并且運行在一個進程中,那么任何一點的改變都會引起整個應用的重新發(fā)布,但是將這個應用拆解為多個服務,你可以期待每個服務的變更僅需要發(fā)布相應的服務就可以,當然這也不是絕對的,比如導致服務接口變更的更新就需要相應服務的變化,但是良好的架構設計是通過聚合服務邊界并且按照合約實現(xiàn)服務演化,最大限度地減少因為改變影響其他地方。
把服務當成組件的另一個考慮是這會擁有更加清晰的接口,大多數(shù)的語言并沒有一個很好的機制來定義一個明確顯式的發(fā)布接口,通常只有文檔和規(guī)范說明,讓用戶避免組件間過度緊密而導致高耦合,通過顯示的遠程調用機制,可以避免這種情況。
使用服務也有其自身的缺點,遠程調用比進程內部調用更加消耗性能,而且遠程的API往往是粗粒度的,用起來不是很友好,對組件的職責進行變更,也會影響到進程間的交互,那么操作起來也比較困難。
第一個可能性,我們看到每個服務是運行在獨立的進程上的。注意,這只是第一個可能性。服務也可以由多個進程組成,它們是同時開發(fā)和部署的,如果一個應用進程和一個僅由該服務使用的數(shù)據(jù)庫。
圍繞業(yè)務能力進行組織
當我們把一個大的應用拆分成小的部分時,我們的注意力主要集中在技術層面,拆分成UI團隊、服務端的邏輯團隊和數(shù)據(jù)庫團隊。當使用這種標準對團隊進行劃分時,甚至一個非常小的更變都將導致跨團隊間項目協(xié)作,從而消耗時間和預算審批。一個高效的團隊會針對這種情況進行改善,關注它們所涉及的應用邏輯,并從中做出較好的選擇。換句話說,邏輯無處不在。康威定律就是一個例子。
一個組織的溝通結構反映了其設計的系統(tǒng)的結構
-- Melvyn Conway, 1967
微服務的劃分方法有所不同,它更傾向于圍繞業(yè)務功能對服務結構進行劃分、拆解,這些服務可以采用不同的技術棧來實現(xiàn),包括用戶界面,持久層存儲,或任何對外協(xié)作,因此團隊應該是跨職能的,包括開發(fā)所需要的全部技術:用戶體驗、數(shù)據(jù)庫和項目管理。
按照這種方式組織的公司是 www.comparethemarket.com,跨職能團隊負責建立和操作每個產(chǎn)品并且每個產(chǎn)品都被分成若干單獨的服務通過消息進行通信。
大型的單體應用也可以按照業(yè)務功能進行模塊化的,盡管這種例子不常見。當然,我們也會敦促一個大型團隊在構建一個單體應用時按照業(yè)務線來進行劃分,我們能看到主要問題在于,這種組件形式會導致很多的上下文依賴,如果這個系統(tǒng)跨越很多模塊邊界,對于一個單獨團隊是很難在短時間解決問題的。此外,我們發(fā)現(xiàn)模塊化方式需要大量的規(guī)范去強制執(zhí)行,而服務組件明確的劃分,使得團隊間的邊界也變得清晰起來。
產(chǎn)品不是項目
大多數(shù)的開發(fā)工作是使用這樣一種模型:其目的是完成可以交付的軟件,軟件開發(fā)完成就交給了維護團隊,該項目組也就解散了。
微服務的支持者建議避免這種模型,認為一個團隊應該負責產(chǎn)品的整個生命周期,一個很通用的概念就是Amazon’s的“you build, you run it”,它要求開發(fā)團隊對軟件產(chǎn)品的整個生命周期負責,這使得開發(fā)人員可以每天都關注產(chǎn)品的運行情況,而且也能夠與用戶保持緊密的聯(lián)系,做一些必要的支持工作。
產(chǎn)品方式開發(fā)意味著與業(yè)務能力緊緊捆綁在一起,而不是將軟件看成是一系列完成的功能,他們會關注如何讓軟件幫助其用戶提升業(yè)務能力。
單體應用也可以采用上述產(chǎn)品的理念,但是更小粒度的服務可以更容易的創(chuàng)建開發(fā)者與用戶之間的關系。