Martin Flower《微服務》

本文為Martin Flower關於微服務的文章《MicroServices》,非常經典的微服務必看文章。轉自:https://www.cnblogs.com/liuning8023/p/4493156.html

微服務


“微服務架構(Microservice Architecture)”一詞在過去幾年裡廣泛的傳播,它用於描述一種設計應用程序的特別方式,作為一套獨立可部署的服務。目前,這種架構方式還沒有準確的定義,但是在圍繞業務能力的組織、自動部署(automated deployment)、端智能(intelligence in the endpoints)、語言和數據的分散控制,卻有著某種共同的特徵。

“微服務(Microservices)”——只不過在滿大街充斥的軟件架構中的一新名詞而已。儘管我們非常鄙視這樣的東西,但是這玩意所描述的軟件風格,越來越引起我們的注意。在過去幾年裡,我們發現越來越多的項目開始使用這種風格,以至於我們身邊的同事在構建企業級應用時,把它理所當然的認為這是一種默認開發形式。然而,很不幸,微服務風格是什麼,應該怎麼開發,關於這樣的理論描述卻很難找到。

簡而言之,微服務架構風格,就像是把一個單獨的應用程序開發為一套小服務,每個小服務運行在自己的進程中,並使用輕量級機制通信,通常是 HTTP API。這些服務圍繞業務能力來構建,並通過完全自動化部署機制來獨立部署。這些服務使用不同的編程語言書寫,以及不同數據存儲技術,並保持最低限度的集中式管理。

在開始介紹微服務風格(microservice style)前,比較一下整體風格(monolithic style)是很有幫助的:一個完整應用程序(monolithic application)構建成一個單獨的單元。企業級應用通常被構建成三個主要部分:客戶端用戶界面(由運行在客戶機器上的瀏覽器的 HTML 頁面、Javascript 組成)、數據庫(由許多的表構成一個通用的、相互關聯的數據管理系統)、服務端應用。服務端應用處理 HTTP 請求,執行領域邏輯(domain logic),檢索並更新數據庫中的數據,使用適當的 HTML 視圖發送給瀏覽器。服務端應用是完整的 ,是一個單獨的的邏輯執行。任何對系統的改變都涉及到重新構建和部署一個新版本的服務端應用程序。

這樣的整體服務(monolithic server)是一種構建系統很自然的方式。雖然你可以利用開發語基礎特性把應用程序劃分成類、函數、命名空間,但所有你處理請求的邏輯都運行在一個單獨的進程中。在某些場景中,開發者可以在的筆計本上開發、測試應用,然後利用部署通道來保證經過正常測試的變更,發佈到產品中。你也可以使用橫向擴展,通過負載均衡將多個應用部署到多臺服務器上。

整體應用程序(Monolithic applications)相當成功,但是越來越多的人感覺到有點不妥,特別是在雲中部署時。變更發佈週期被綁定了——只是變更應用程序的一小部分,卻要求整個重新構建和部署。隨著時間的推移,很難再保持一個好的模塊化結構,使得一個模塊的變更很難不影響到其它模塊。擴展就需要整個應用程序的擴展,而不能進行部分擴展。

Martin Flower《微服務》

圖 1 整理架構與微服務架構

這導致了微服務架構風格(microservice architectural style)的出現:把應用程序構建為一套服務。事實是,服務可以獨立部署和擴展,每個服務提供了一個堅實的模塊邊界,甚至不同的服務可以用不同的編程語言編寫。它們可以被不同的團隊管理。

我們必須說,微服務風格不是什麼新東西,它至少可以追溯到 Unix 的設計原則。但是並沒有太多人考慮微服務架構,如果他們用了,那麼很多軟件都會更好。

微服務風格的特性


微服務風格並沒有一個正式的定義,但我們可以嘗試描述一下微服務風格所具有的共同特點。並不是所有的微服務風格都要具有所有的特性,但我們期望常見的微服務都應該有這些特性。我們的意圖是嘗試描述我們工作中或者在其它我們瞭解的組件中所理解的微服務。特別是,我們不依賴於那些已經明確過的定義。

組件化(Componentization )與服務(Services)

自從我們開始軟件行業以來,一直希望由組件構建系統,就像我們在物理世界所看到的一樣。在過去的幾十年裡,我們已經看到了公共庫的大量簡編取得了相當的進步,這些庫是大部分語言平臺的一部分。

當我們談論組件時,可能會陷入一個困境——什麼是組件。我們的定義是,組件(component)是一個可獨立替換和升級的軟件單元。

微服務架構(Microservice architectures)會使用庫(libraries),但組件化軟件的主要方式是把它拆分成服務。我們把庫(libraries)定義為組件,這些組件被鏈接到程序,並通過內存中函數調用(in-memory function calls)來調用,而服務(services )是進程外組件(out-of-process components),他們利用某個機制通信,比如 WebService 請求,或遠程過程調用(remote procedure call)。組件和服務在很多面向對象編程中是不同的概念。

把服務當成組件(而不是組件庫)的一個主要原因是,服務可以獨立部署。如果你的應用程序是由一個單獨進程中的很多庫組成,那麼對任何一個組件的改變都將導致必須重新部署整個應用程序。但是如果你把應用程序拆分成很多服務,那你只需要重新部署那個改變的服務。當然,這也不是絕對的,有些服務會改變導致協調的服務接口,但是一個好的微服務架構的目標就是通過在服務契約(service contracts)中解耦服務的邊界和進化機制來避免這些。

另一個考慮是,把服務當組件將擁有更清晰的組件接口。大多數開發語言都沒有一個良好的機制來定義一個發佈的接口(Published Interface)。發佈的接口是指一個類向外公開的成員,比如 Java 中的聲明為 Public 的成員,C# 中聲明為非 Internal 的成員。通常只有在文檔和規範中會說明,這是為了讓避免客戶端破壞組件的封裝性,阻止組件間緊耦合。服務通過使用公開遠程調用機制可以很容易避免這些。

像這樣使用服務也有不足之處。遠程調用比進制內調用更消耗資源,因此遠程 API 需要粗粒度(coarser-grained),但這會比較難使用。如果你需要調整組件間的職責分配,當跨越進程邊界時,這樣做將會很難。

一個可能是,我們看到,服務可以映射到運行時進程(runtime processes)上,但也只是一個可能。服務可以由多個進程組成,它們會同時開發和部署,例如一個應用程序進程和一個只能由這個服務使用的數據庫。

圍繞業務功能的組織

當尋找把一個大的應用程序拆分成小的部分時,通常管理都會集中在技術層面,UI團隊、服務端業務邏輯團隊和數據庫團隊。當使用這種標準對團隊進行劃分時,甚至小小的更變都將導致跨團隊項目協作,從而消耗時間和預算審批。一個高效的團隊會針對這種情況進行改善,兩權相害取其輕。業務邏輯無處不在。實踐中,這就是 Conway's Law 的一個例子。

設計一個系統的任何組織(廣義上)都會產生這樣一種設計,其結構是組織交流結構的複製。

——Melvyn Conway, 1967

Melvyn Conway 的意識是,像下圖所展示的,設計一個系統時,將人員劃分為 UI 團隊,中間件團隊,DBA 團隊,那麼相應地,軟件系統也就會自然地被劃分為 UI 界面,中間件系統,數據庫。

Martin Flower《微服務》

圖 2 實踐中的 Conway's Law

微服務(microservice )的劃分方法不同,它傾向圍繞業務功能的組織來分割服務。這些服務實現商業領域的軟件,包括用戶界面,持久化存儲,任何的外部協作。因此,團隊是跨職能的(cross-functional),包含開發過程所要求的所有技能:用戶體驗(user-experience)、數據庫(database)和項目管理(project management)。

Martin Flower《微服務》

圖 3 通過團隊邊界強調服務邊界

www.comparethemarket.com就是採用這種組織形式。跨職能的團隊同時負責構建和運營每個產品,每個產品被分割成許多單個的服務,這些服務通過消息總線(Message Bus)通信。

大型的整體應用程序(monolithic applications)也可以按照業務功能進行模塊化(modularized),儘管這樣情況不常見。當然,我們可以敦促一個構建整體應用程序(monolithic application )的大型團隊,按業務線來分割自己。我們已經看到的主要問題是,這種組件形式會導致很多的依賴。如果整體應用程序(monolithic applications)跨越很多模塊邊界(modular boundaries ),那麼對於團隊的每個成員短期內修復它們是很困難的。此外,我們發現,模塊化需要大量的強制規範。服務組件所要求的必需的更明確的分離使得保持團隊邊界清晰更加容易。

產品不是項目

大部分的軟件開發者都使用這樣的項目模式:至力於提供一些被認為是完整的軟件。交付一個他們認為完成的軟件。軟件移交給運維組織,然後,解散構建軟件的團隊。

微服務(Microservice )的支持者認為這種做法是不可取的,並提議團隊應該負責產品的整個生命週期。Amazon 理念是“你構建,你運維(you build, you run it)”,要求開發團隊對軟件產品的整個生命週期負責。這要求開發者每天都關注他們的軟件運行如何,增加更用戶的聯繫,同時承擔一些售後支持。

產品的理念,跟業務能力聯繫起來。不是著眼於完成一套功能的軟件,而是有一個持續的關係,是如何能夠幫助軟件及其用戶提升業務能力。

為什麼相同的方法不能用在整體應用程序(monolithic applications),但更小的服務粒度能夠使創建服務的開發者與使用者之間的個人聯繫更容易。

強化終端及弱化通道

當構建不同的進程間通信機制的時候,我們發現有許多的產品和方法能夠把更加有效方法強加入的通信機制中。比如企業服務總線(ESB),這樣的產品提供更有效的方式改進通信過程中的路由、編碼、傳輸、以及業務處理規則。

微服務傾向於做如下的選擇:強化終端及弱化通道。微服務的應用致力松耦合和高內聚:採用單獨的業務邏輯,表現的更像經典Unix意義上的過濾器一樣,接受請求、處理業務邏輯、返回響應。它們更喜歡簡單的REST風格,而不是複雜的協議,如WS或者BPEL或者集中式框架。

有兩種協議最經常被使用到:包含資源API的HTTP的請求-響應和輕量級消息通信協議。最為重要的建議為:

善於利用網絡,而不是限制(Be of the web, not behind the web)。

——Ian Robinson

微服務團隊採用這樣的原則和規範:基於互聯網(廣義上,包含Unix系統)構建系統。這樣經常使用的資源幾乎不用什麼的代價就可以被開發者或者運行商緩存。

第二種做法是通過輕量級消息總線來發布消息。這種的通信協議非常的單一(單一到只負責消息路由),像RabbitMQ或者ZeroMQ這樣的簡單的實現甚至像可靠的異步機制都沒提供,以至於需要依賴產生或者消費消息的終端或者服務來處理這類問題。

在整體工風格中,組件在進程內執行,進程間的消息通信通常通過調用方法或者回調函數。從整體式風格到微服務框架最大的問題在於通信方式的變更。從內存內部原始的調用變成遠程調用,產生的大量的不可靠通信。因此,你需要把粗粒度的方法成更加細粒度的通信。

分散治理

集中治理的一種好處是在單一平臺上進行標準化。經驗表明這種趨勢的好處在縮小,因為並不是所有的問題都相同,而且解決方案並不是萬能的。我們更加傾向於採用適當的工具解決適當的問題,整體式的應用在一定程度上比多語言環境更有優勢,但也適合所有的情況。

把整體式框架中的組件,拆分成不同的服務,我們在構建它們時有更多的選擇。你想用Node.js去開發報表頁面嗎?做吧。用C++來構建時時性要求高的組件?很好。你想以在不同類型的數據庫中切換,來提高組件的讀取性能?我們現在有技術手段來實現它了。

當然,你是可以做更多的選擇,但也不意味的你就可以這樣做,因為你的系統使用這種方式進行侵害意味著你已經有的決定。

採用微服務的團隊更喜歡不同的標準。他們不會把這些標準寫在紙上,而是喜歡這樣的思想:開發有用的工具來解決開發者遇到的相似的問題。這些工具通常從實現中成長起來,並進行的廣泛範圍內分享,當然,它們有時,並不一定,會採用開源模式。現在開源的做法也變得越來越普遍,git或者github成為了它們事實上的版本控制系統。

Netfix就是這樣的一個組織,它是非常好的一個例子。分享有用的、尤其是經過實踐的代碼庫激勵著其它的開發著也使用相似的方式來解決相似的問題,當然,也保留著根據需要使用不同的方法的權力。共享庫更關注於數據存儲、進程內通信以及我們接下來做討論到的自動化等這些問題上。

微服務社區中,開銷問題特別引人注意。這並不是說,社區不認為服務交互的價值。相反,正是因為發現到它的價值。這使得他們在尋找各種方法來解決它們。如Tolearant Reader和Consumer-Driven Contracts這樣的設計模式就經常被微服務使用。這些模式解決了獨立服務在交互過程中的消耗問題。使用Consumer-Driven Contracts增加了你的信心,並實現了快速的反饋機制。事實上,我們知道澳大利亞的一個團隊致力使用Consumer-Drvien Contracts開發新的服務。他們使用簡單的工程,幫助他們定義服務的接口。使得在新服務的代碼開始編寫之前,這些接口就成為自動化構建的一個部分。構建出來的服務,只需要指出這些接口適用的範圍,一個優雅的方法避免了新軟件中的'YAGNI '困境。這些技術和工具在使用過程中完善,通過減少服務間的耦合,限制了集中式管理的需求。

也許分散治理普及於亞馬遜“編譯它,運維它”的理念。團隊為他們開發的軟件負全部責任,也包含7*24小時的運行。全責任的方式並不常見,但是我們確實發現越來越多的公司在他們的團隊中所推廣。Netfix是另外一個接受這種理念的組件。每天凌晨3點被鬧鐘吵醒,因為你非常的關注寫的代碼質量。這在傳統的集中式治理中這是一樣多麼不思議的事情呀。

分散數據管理

對數據的分散管理有多種不同的表現形式。最為抽象層次,它意味著不同系統中的通用概念是不同的。這帶來的覺問題是大型的跨系統整合時,用戶使用不同的售後支持將得到不同的促銷信息。這種情況叫做並沒有給用戶顯示所有的促銷手段。不同的語法確實存在相同的詞義或者(更差)相同的詞義。

應用之間這個問題很普遍,但應用內部這個問題也存在,特別是當應用拆分成不同的組件時。對待這個問題非常有用的方式為Bounded Context的領域驅動設計。DDD把複雜的領域拆分成不同上下文邊界以及它們之間的關係。這樣的過程對於整體架構和微服務框架都很有用,但是服務間存在著明顯的關係,幫助我們對上下文邊界進行區分,同時也像我們在業務功能中談到的,強行拆分。

當對概念模式下決心進行分散管理時,微服務也決定著分散數據管理。當整體式的應用使用單一邏輯數據庫對數據持久化時,企業通常選擇在應用的範圍內使用一個數據庫,這些決定也受廠商的商業權限模式驅動。微服務讓每個服務管理自己的數據庫:無論是相同數據庫的不同實例,或者是不同的數據庫系統。這種方法叫Polyglot Persistence。你可以把這種方法用在整體架構中,但是它更常見於微服務架構中。

Martin Flower《微服務》

圖 4 Polyglot Persistence

微服務音分散數據現任意味著管理數據更新。處理數據更新的常用方法是使用事務來保證不同的資源修改數據庫的一致性。這種方法通常在整體架構中使用。

使用事務是因為它能夠幫助處理一至性問題,但對時間的消耗是嚴重的,這給跨服務操作帶來難題。分佈式事務非常難以實施,因此微服務架構強調服務間事務的協調,並清楚的認識一致性只能是最終一致性以及通過補償運算處理問題。

選擇處理不一致問題對於開發團隊來說是新的挑戰,但是也是一個常見的業務實踐模式。通常業務上允許一定的不一致以滿足快速響應的需求,但同時也採用一些恢復的進程來處理這種錯誤。當業務上處理強一致性消耗比處理錯誤的消耗少時,這種付出是值的的。

基礎設施自動化

基礎設施自動化技術在過去幾年中得到了長足的發展:雲計算,特別是AWS的發展,減少了構建、發佈、運維微服務的複雜性。

許多使用微服務架構的產品或者系統,它們的團隊擁有豐富的持集部署以及它的前任持續集成的經驗。團隊使用這種方式構建軟件致使更廣泛的依賴基礎設施自動化技術。下圖說明這種構建的流程:

Martin Flower《微服務》

圖 5 基本的構建流程

儘管這不是介紹自動部署的文章,但我們也打算介紹一下它的主要特徵。我們希望我們的軟件應該這樣方便的工作,因此我們需要更多的自動化測試。流程中工作的軟件改進意味著我們能自動的部署到各種新的環境中。

整體風格的應用相當開心的在各種環境中構建、測試、發佈。事實證明,一旦你打算投資一條整體架構應用自動化的的生產線,那麼你會發現發佈更多的應用似乎非不那麼的可怕。記住,CD(持續部署)的一個目標在於讓發佈變得無趣,因此無論是一個還是三個應用,它都一樣的無趣。

另一個方面,我們發現使用微服務的團隊更加依賴於基礎設施的自動化。相比之下,在整體架構也微服務架構中,儘管發佈的場景不同,但發佈工作的無趣並沒有多大的區別。

Martin Flower《微服務》

圖 6 模塊化部署的區別

容錯性設計

使用服務作為組件的一個結果在於應用需要有能容忍服務的故障的設計。任務服務可能因為供應商的不可靠而故障,客戶端需要儘可能的優化這種場景的響應。跟整體構架相比,這是一個缺點,因為它帶來的額外的複雜性。這將讓微服務團隊時刻的想到服務故障的情況下用戶的體驗。Netflix 的Simian Army可以為每個應用的服務及數據中心提供日常故障檢測和恢復。

這種產品中的自動化測試可以讓大部分的運維團隊正常的上下班。這並不意味著整體構架的應用沒有這麼精巧的監控配置,只是在我們的經驗中它並不常見。

由於服務可以隨時故障,快速故障檢測,乃至,自動恢復變更非常重要。微服務應用把實時的監控放在應用的各個階段中,檢測構架元素(每秒數據庫的接收的請求數)和業務相關的指標(把分鐘接收的定單數)。監控系統可以提供一種早期故障告警系統,讓開發團隊跟進並調查。

對於微服務框架來說,這相當重要,因為微服務相互的通信可能導致緊急意外行為。許多專家車稱讚這種緊急事件的價值,但事實是這種緊急行為有時是災難。監控是至關重要的,它能快速發現這種緊急不良行為,讓我們迅速修復它。

整體架構,跟微服務一樣,在構建時是通明的,實情上,它們就是這樣子的。它們不同之處在於,你需要清楚的認識到不同進程間運行的服務是不相關的。庫對於同一進程是透明的,也因此不那麼重要了。

微服務團隊期望清楚的監控和記錄每個服務的配置,比如使用儀表盤顯示上/下線狀態、各種運維和業務相關的指標。對斷路器(circuit breaker)狀態、目前的吞吐量和時延細節,我們也會經常遇到。

設計改進

微服務實踐者,通常有不斷改進設計的背景,他們把服務分解成進一步的工具。這些工具可以讓應用開發者在不改變速度情況下,控制都他們的應用的需求變更。變更控制不意味首減少變更,而是使用適當的方式和工具,讓它更加頻繁,至少,很好讓它變得可控。

不論如何,當你試圖軟件系統拆分成組件時,你將面臨著如何拆分的問題。那麼我們的決定拆分我們應用的原則是什麼呢?首要的因素,組件可以被獨立替換和更新的,這意味著我們尋找的關鍵在於,我們要想象著重寫一個組件而不影響它們之前的協作關係。事實上,許多的微服務小組給它進一步的預期:服務應該能夠報廢的,而不是要長久的發展的。

Guardian網站就是這方面的一個優秀的例子,它初期被設計和構建成一個整體架構,但它已經向微服務的發展了。整體構架仍然是它網站的核心,但是他們使用微服務來增加那些使用整體架構API的新特性。這種方法增加這些臨時的特性非常方便,比如運動新聞的特稿。這樣站點的一個部分可以使用快速的開發語言迅速整合起來,當它過時後可以一次性移除。我們發現一家金融機構用相似的方法增加新的市場營銷活動,數週或者幾個月後把它撤銷。

可代替是模塊化開發中的一個特例,它是用模塊來應對需要變更的。你希望讓變更是相同模塊,相同週期中進行變化而已。系統的某些很小做變更部分,也應該放在不同的服務中,這樣它們更容易讓它們消亡。如果你發現兩個服務一直重複的變更時,這就是一個要合併它們的信號了。

把組件改成服務,增加了細化發佈計劃的一個機會。整體構架的任務變更需要整個應用的完整的構建和發佈。然而,使用微服務,你只需要發佈你要修改的服務就可以了。這將簡化和加速你的發佈週期。缺點是你需要為一個變更服務發佈可能中斷用戶的體驗而擔心。傳統的集成方法是使用版本來處理這些問題,但是微服務版本僅是最後的通告手段。我們需要在設計服務時儘可能的容忍供應商的變更,以避免提供多個版本。

微服務是未來嗎?

我們寫這篇文章的主要目的在於解釋微服務的主要思想和原則。但是發時間做這事的時候,我們清醒的認識到微服務構架風格是一個非常重要的想法:一個值得企業應用中認真考慮的東西。我們最近使用這種風格構建了幾個系統,認識那些也使用和喜歡這種方法的愛好者。

我們認識的使用這種方式的先行者,包含亞馬遜、Netflix、The Guardian、The UK Government Digital Service、realestate.com.au、Forward和comparethemarket.com。2013看的巡迴會議充滿了向正在想成為微服務一分子的公司,包含Travis CI。此外,大量的組件正在從事我們認為是微服務的事,只是沒有使用微服務的名字而已。(通常,它們被打上SOA的標籤,儘管,我們認為SOA有許多不同的地方。)

儘管有這些積極的經驗,然後,我們也不急於確認微服務是未來軟件架構方向。至今為止,我們的經驗與整體風格的應該中相比出來的是有優勢的,但是我們意識知這樣的事實,我們並沒有足夠的時間來證明我們的論證。

你所使用的架構通常是你開發出來後,使用的幾年的實際成果。我們看到這些工程是在一個優秀的團隊,帶著對模塊化的強烈追求,使用在過去幾年中已經衰退的整體架構構建出來的。許多人相信,這種衰退不太可能與微服務有關,因為服務邊界是清晰的並且很難再完善的。然而,當我們還沒看到足夠多的系統運行足夠長時間時,我們不能肯定微服務構架是成熟的。

當然,還有原因就是,有人期望微服務構架不夠成熟。在組件化方面的任何努力,其成功都依賴於軟件如何拆分成適合的組件。指出組件化的準確邊界應該在那,這是非常困難的。改良設計要承認邊界的權益困境和因此帶來的易於重構的重要性。但是當你的組件是被遠程通信的服務時,重構比進程內的庫又要困難的多。服務邊界上的代碼遷移是困難的,任務接口的變更需要參與者的共同協作,向後兼容的層次需要被增加,測試也變更更加複雜。

另一個問題在於,如果組件並沒有清晰的劃分,你的工作的複雜性將從組件內部轉向組件間的關係。做這事不僅要圍繞著複雜,它也要面對著不清晰和更難控制的地方。很容易想到,當你在一個小的、簡單的組件內找東西,總比在沒有關係的混亂的服務間要容易。

最後,團隊技能也是重要的因素。新的技術傾向於被掌握更多的技能的團隊使用。但是掌握多技能的團隊中使用的技巧在較少技能的團隊中並不是必需的。我們發現大量的少技能的團隊構建混亂的整合構架,但是它要發時間去證明使用微服務在這種情況下會發生什麼。一個糟糕的團隊通常開發糟糕的系統:很難說,微服務在這種情況下是否能幫助它們,還是破壞它們。

一個理性的爭議在於,我們聽說,你不應該從微服務構架開始做。最好從整體構架開發,做模塊化開發,然後當整體構架出現問題是再把模塊化拆分成服務。(儘管這種建議不是好主意,因為一個好的進程內接口並不是一個好的服務接口。)

因此我們持這種謹慎的樂觀。到目前為止,我們還沒有足夠認識,關於微構架能否被大範圍的推廣。我們不能肯定的說,我們要終結什麼,但是軟件開發的挑戰在於你只能在不完整的信息中決定你目前要處理的問題。

其它


微服務系統多大?

儘管“微服務”一詞在架構風格中越來越流行,它的名字很不辛讓人關注它的服務大小,以及對“微”這個組成的爭議。在我們與微服務實踐者的談話中,我們發現了服務的大小範圍。被報道的最大團隊遵循亞馬遜Tow Pizaa團隊理念(比如,一個團隊吃兩個比薩就可以了。),這意味著不超過20號(一打)人。我們發現最小配置是半打的團隊支撐起一打的服務。

這也引發這樣的考慮:規模為一個服務一打人到一個服務一個人的團隊打上微服務的標籤。此刻我們認為,它們是一樣的,但是隨著對這種風格的深入研究,也存在我們改變我們的想法的可能。

微服務與SOA

當前我們談到微服務時,通常會問,這是不是我們20年前討論的面向服務架構(SOA)。這是一個很好的觀點,因為微服務風格也SOA所提倡的一些優勢非常相似。儘管如此,問題在於SOA意味的太多不同的東西了,因此通常時候我們談的所謂“SOA”時,它與我們談論的風格不一至,因為它通常是指在整體風格應用中的ESB。

此外,我們發現面向服務的風格是這麼的拙劣:從試圖使用ESB隱藏複雜性, 到使用多年才認識到發費數百美元卻沒產生任務價值這樣的失敗,到集中治理模式抑制變更。而且這些問題往往很難發現。

可以肯定的時,微服務社區中使用的許多的技術都開發者是從大型機構的整合服務經驗中發展來的。Tolerant Reader模式就是這樣的一個例子。由於互聯網的發展,利用簡單的協議這種方法,讓它從這些經驗傳達的出來。這是從已經很複雜的集中式標準中的一種反模式,坦白的說,真讓人驚歎。(無論何時,當你需要用一個服務來管理你的所有的服務,你就知道這很麻煩。)

SOA的這種常見行為讓微服務的提倡者拒絕打上SOA的標籤,儘管有人認為微服務是從SOA中發展而來的,或許面向服務是對的。無論如何,事實上SOA表達這麼多的含義,它給一個團隊清醒的認識到這種構架風格就已經值的了。

多語言,多選擇

JVM做為一個平臺,它的增長就是一個平臺中運行多語言的最大的例子。過去二十年中,它通常做為更高層次語言的殼,以達到更高層次的抽象。比如,研究它的內部結構,、使用低級的語言寫更高效的代碼。儘管如此,許多整體風格並不需要這種層次的性能優化或者在語法及高層次上的抽象,這很常見(讓我們很失望)。此外整體構架通常意味著使用單一的語言,這也限制著使用技術的數量。

實踐標準和強制標準

它有點尷尬,微服務團隊傾向於避免這種通常由企業架構隊伍定製的僵硬的強制標準,但是它們卻非常樂於甚至推廣這些開放的標準,如HTTP、ATOM、其它微規範。

關鍵的不同在這些標準是怎麼開發出來的,以及它們是怎麼被推廣的。標準被一些組件管理,如IETF認證標準,僅當它們在互聯網上有幾個在用的實現,通常源自於開源工程的成功應用。

這些標準單獨分離出來,與那種在企業中通常有沒有什麼編碼經驗的或者沒有什麼影響力的廠商標準進行區別。

讓做對事更容易

一方面,我們發現在持續發佈、部署越來越多的使用自動化,是很多有用的工具開發出來幫助開發者和運營商的努力結果。為打包、代碼管理、支撐服務的工具,或者增加標準監控的記錄的工具,現在都非常常見了。網絡中最好的,可能就是Netflix's的開源工具,但是包含Dropwizard在內的其它工具也被廣泛的使用著。

斷路器(circuit breaker)和產品中現有的代碼

斷路器(circuit breaker)出現在《Realease It!》一書中,與Bulkhead和Timeout這樣的模式放在一起。實施起來,這些模式用於構建通信應用時相當的重要。Netflix的博客在解釋它們的應用時,做了大量的工作。

同步是有害的

任務時候,你在服務間的調用使用同步的方法,都會遇到宕機時間的乘積效應。簡單的說,你的系統宕機時間是你係統的單獨組件的宕機時間的乘積。你面臨的選擇使用異步或者管理宕機時間。在www.guardian.co.uk中,它們在新平臺中使用一種簡單的規則來實現它:在Netflix中每次用戶請求的同步調用,他們重新設計的平臺API都會把它構建成異步的API來執行。


分享到:


相關文章: