本文借助於https://www.cnblogs.com/liuning8023/p/4493156.html這篇博客的大部分,但有一小部分是我覺得他翻譯的不通順的或者是我自己的理解。本文僅作筆記,如果侵權一定刪除
新名詞:服務網格
什么是微服務?
中文:https://www.cnblogs.com/liuning8023/p/4493156.html
英文:http://martinfowler.com/articles/microservices.html
“微服務架構(Microservice Architecture)”
圍繞業務能力的組織、自動部署(automated deployment)、端智能(intelligence in the endpoints)、語言和數據的分散控制,卻有着某種共同的特征。
微服務是一種軟件架構風格
把一個單獨的應用程序開發為一套小服務,每個小服務運行在自己的進程中,並使用輕量級機制通信,通常是 HTTP API。
圍繞業務能力來構建,並通過完全自動化部署機制來獨立部署。這些服務使用不同的編程語言書寫,以及不同數據存儲技術,並保持最低限度的集中式管理。
微服務
“微服務架構(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)相當成功,但是越來越多的人感覺到有點不妥,特別是在雲中部署時。變更發布周期被綁定了——只是變更應用程序的一小部分,卻要求整個重新構建和部署。隨着時間的推移,很難再保持一個好的模塊化結構,使得一個模塊的變更很難不影響到其它模塊。擴展就需要整個應用程序的擴展,而不能進行部分擴展。
這導致了微服務架構風格(microservice architectural style)的出現:把應用程序構建為一套服務。事實是,服務可以獨立部署和擴展,每個服務提供了一個堅實的模塊邊界,甚至不同的服務可以用不同的編程語言編寫。它們可以被不同的團隊管理。
我們必須說,微服務風格不是什么新東西,它至少可以追溯到 Unix 的設計原則。但是並沒有太多人考慮微服務架構,如果他們用了,那么很多軟件都會更好
微服務風格的特性
我們並不能說微服務風格有一個准確的定義,但是我們可以描述一下我們認為符合微服務架構的常見(common)特點。並不是所有的微服務都要具有所有的特性,但我們希望常見的微服務都應該有這些特性。
雖然我們(作者們)是這個相對松散的社區(譯者:認為是使用微服務的全體人員)的積極成員,我們的目的是描述一下我們在工作中的所見和我們所了解的團隊中類似的做法( in similar efforts by teams we know of)。我們並不是企圖下一個准確定義。
服務組件化
自從我們開始軟件行業以來,一直希望由組件構建系統,就像我們在物理世界所看到的一樣。在過去的幾十年里,我們已經看到了公共庫的大量簡編取得了相當的進步,這些庫是大部分語言平台的一部分。
當我們談論組件時,可能會陷入一個困境——什么是組件。我們的定義是,組件(component)是一個可獨立替換和升級的軟件單元。微服務架構(Microservice architectures)會使用庫(libraries),但組件化軟件的主要方式是把它拆分成服務。我們把庫(libraries)定義為組件,這些組件被鏈接到程序,並通過內存中函數調用(in-memory function calls)來調用,而服務(services )是進程外組件(out-of-process components),他們利用某個機制通信,比如 WebService 請求,或遠程過程調用(remote procedure call)。這個服務和許多面向對象的面向中的服務對象的概念是不同的。(This is a different concept to that of a service object in many OO programs)。
服務當成組件(而不是組件庫)的一個主要原因是,服務可以獨立部署(deployable)。如果你的應用程序是由一個單獨進程(process)中的很多庫組成,那么對任何一個組件的改變都將導致必須重新部署整個應用程序。但是如果你把應用程序拆分(decomposed)成很多服務,那你只需要重新部署那個改變的服務.當然,這也不是絕對的,有些服務會改變導致耦合(coordination),但是一個好的微服務架構的目標就是通過在服務約定(service contracts)中內聚(cohesive)服務邊界和進化機制來避免這些。
另一個考慮是,把服務當組件將擁有更清晰的組件接口。大多數開發語言都沒有一個良好的機制(machanism)來定義一個明確的(explicit)公共接口(Published Interface)。這個公共接口只是一個文檔或者規則阻止代理打破組件封裝。服務使用公開遠程調用機制可以很容易避免這些。
使用服務也有缺點。遠程調用比進制內調用更消耗資源,因此遠程 API 需要粗粒度(coarser-grained),但這會比較難使用。如果你需要在跨越進程邊界時調整組件間的職責分配會很難。
在第一種可能中,我們可以看到服務(sevices)可以映射到運行時進程(runtime processes)上,但這只是第一種可能。服務可能包含開發和部署一起的多個流程,例如僅由該服務使用的應用程序流程和數據庫。
圍繞業務功能的組織
當希望將大型應用程序拆分為多個部分時,管理層通常將重點放在技術層,領導UI團隊,服務器端邏輯團隊和數據庫團隊(leading to UI teams, server-side logic teams, and database teams.)。一個高效的團隊會針對這種情況進行改善,兩權相害取其輕--重視他們做的任何應用中的邏輯。業務邏輯無處不在(just force the logic into whichever application they have access to)。實踐中,這就是 Conway's Law 的一個例子。
設計系統(廣泛定義)的任何組織都將產生一種設計,該設計結構是組織交流結構的副本
elvyn Conway 的意識是,像下圖所展示的,設計一個系統時,將人員划分為 UI 團隊,中間件團隊,DBA 團隊,那么相應地,軟件系統也就會自然地被划分為 UI 界面,中間件系統,數據庫。
圖 2 實踐中的 Conway's Law
微服務(microservice )的划分方法不同,它傾向圍繞業務功能的組織來分割服務。這些服務實現商業領域的軟件,包括用戶界面,持久化存儲,任何的外部協作。因此,團隊是跨職能的(cross-functional),包含開發過程所要求的所有技能:用戶體驗(user-experience)、數據庫(database)和項目管理(project management)。
微服務的通常特性
圖 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或者集中式框架。
微服務團隊采用這樣的原則和規范:基於互聯網(廣義上,包含Unix系統)構建系統。這樣經常使用的資源幾乎不用什么的代價就可以被開發者或者運行商緩存。
第二種做法是通過輕量級消息總線來發布消息。這種的通信協議非常的單一(單一到只負責消息路由),像RabbitMQ或者ZeroMQ這樣的簡單的實現甚至像可靠的異步機制都沒提供,以至於需要依賴產生或者消費消息的終端或者服務來處理這類問題。
在整體工風格中,組件在進程內執行,進程間的消息通信通常通過調用方法或者回調函數。從整體式風格到微服務框架最大的問題在於通信方式的變更。從內存內部原始調用變成遠程調用,產生的大量的不可靠通信。因此,你需要把粗粒度的方法成更加細粒度的通信。
去中心化
集中治理的后果傾向於是在單一平台上進行標准化。經驗表明這是一種限制(this approach is constricting),因為並不是所有的問題都相同,而且解決方案並不是萬能的。我們更加傾向於采用適當的工具解決適當的問題,整體式的應用在一定程度上比多語言環境更有優勢,這確實有所不同。
把整體式框架中的組件,拆分成不同的服務,我們在構建它們時有更多的選擇。你想用Node.js去開發報表頁面嗎?做吧。用C++來構建時時性要求高的組件?很好。你想以在不同類型的數據庫中切換,來提高組件的讀取性能?我們現在有技術手段來實現它了
當然,你是可以做更多的選擇,但也不意味的你一定要,但是以這種方式對系統進行分區意味着您可以選擇。
采用微服務的團隊更喜歡不同的標准。他們不會把這些標准寫在紙上,而是喜歡這樣的思想:開發有用的工具來解決開發者遇到的相似的問題。這些工具通常收獲於現實(harvest from),並進行的廣泛范圍內分享,當然,它們有時,並不一定,會采用開源模式。現在開源的做法也變得越來越普遍,git或者github成為了它們事實上的版本控制系統。
Netfix就是這樣的一個組織,它是非常好的一個例子。分享有用的、尤其是經過實踐的代碼庫激勵着其它的開發着也使用相似的方式來解決相似的問題,當然,也保留着根據需要使用不同的方法的權力。共享庫更關注於數據存儲、進程內通信以及我們接下來做討論到的自動化等這些問題上。
微服務社區中,開銷(overhead)並不吸引人,但這並不意味着組織不評估服務約束(service contract),相反,因為評估往往更多。這只意味着只是他們正在尋找管理這些合同的不同方法。如Tolearant Reader和Consumer-Driven Contracts這樣的設計模式就經常被微服務使用。這些模式解決了獨立服務在交互過程中的消耗問題。使用Consumer-Driven Contracts增加了你的信心,並實現了快速的反饋機制。事實上,我們知道澳大利亞的一個團隊致力使用Consumer-Drvien Contracts開發新的服務。他們使用簡單的工程,幫助他們定義服務的接口。使得在新服務的代碼開始編寫之前,這些接口就成為自動化構建的一個部分。構建出來的服務,只需要指出這些接口適用的范圍,一個優雅的方法避免了新軟件中的'YAGNI '困境。這些技術和工具在使用過程中完善,通過減少服務間的耦合,限制了集中式管理的需求。
去中心化管理的高潮也許是亞馬遜推廣的“編譯它,運維它”理念。團隊為他們開發的軟件負全部責任,也包含7*24小時的運行。全責任的方式並不常見,但是我們確實發現越來越多的公司在他們的團隊中所推廣。Netfix是另外一個接受這種理念的組件。每天凌晨3點被鬧鍾吵醒,因為你非常的關注寫的代碼質量。這在傳統的集中式治理中這是一樣多么不思議的事情呀。
去中心化管理數據
:大系統整合,麻煩在於相同屬性有不同含義,可以用領域驅動設計,上下文和服務的關系幫助我們區分,數據存儲中心,每個服務有自己的數據庫,只要最終解決不一致性帶的麻煩比使用一致性事務管理,去中心化管理數據就值得。
對數據的分散管理有多種不同的表現形式。多為抽象層次,它意味着不同系統中的通用概念是不同的。這帶來的普遍問題是大型的跨系統整合時,針對客戶的銷售圖和針對客戶的服務圖是不同的。一些客戶可能在銷售圖中出現,但在服務圖中不會出現。這些不同的系統確實可能出現不同的屬性,壞一點來說,相同的屬性有不同的涵義。(這句話我確實不會翻譯 Some things that are called customers in the sales view may not appear at all in the support view. Those that do may have different attributes and (worse) common attributes with subtly different semantics.)
應用之間這個問題很普遍,但應用內部這個問題也存在,尤其是應用拆分成不同的組件時。對待這個問題非常有用的方式為Bounded Context的領域驅動設計。DDD把復雜的領域拆分成不同上下文邊界以及它們之間的關系。這樣的過程對於整體架構和微服務框架都很有用,服務和上下文邊界天生的關系幫助了我們進行區分,同時也像我們在業務功能中談到的,加強拆分。
除了對概念模型的去中心化的決策外,微服務對數據存儲也是區中心化決策。當整體式的應用使用單一邏輯數據庫對數據持久化時,企業通常選擇在應用的范圍內使用一個數據庫,這些決定也受廠商的商業權限模式驅動。微服務讓每個服務管理自己的數據庫:無論是相同數據庫的不同實例,或者是不同的數據庫系統。這種方法叫Polyglot Persistence。你可以把這種方法用在整體架構中,但是它更常見於微服務架構中。
數據去中心化的數據管理在更新中有應用(Decentralizing responsibility for data across microservices has implications for managing updates. )處理數據更新的常用方法是使用事務來保證不同的資源修改數據庫的一致性。這種方法通常在整體架構中使用。
使用事務是因為它能夠幫助處理一至性問題,但對時間的消耗是嚴重的,這給跨服務操作帶來難題。分布式事務非常難以實施,因此微服務架構強調服務間事務的協調,並清楚的認識一致性只能是最終一致性以及通過補償運算處理問題。
選擇這種方式處理不一致問題對於開發團隊來說是新的挑戰。只要解決錯誤的成本小於在一致性下的業務損失成本,就值得。
基礎設施自動化
基礎設施自動化技術在過去幾年中得到了長足的發展:雲計算,特別是AWS的發展,減少了構建、發布、運維微服務的復雜性。許多使用微服務架構的產品或者系統,它們的團隊擁有豐富的持集部署以及它的前任持續集成的經驗。團隊使用這種方式構建軟件致使更廣泛的依賴基礎設施自動化技術。下圖說明這種構建的流程:
整體風格的應用相當輕松的在各種環境中構建、測試、發布。事實證明,一旦你打算投資一條整體架構應用自動化的的生產線,那么你會發現發布更多的應用似乎非不那么的可怕。記住,CD(持續部署)的一個目標在於讓發布變得不麻煩(boring),因此無論是一個還是三個應用,它都一樣的不麻煩。
我們看到團隊使用廣泛(extensive,廣泛不是外部)的基礎架構自動化的另一個領域是在生產中管理微服務。與我們上面的言論相反,只要部署不麻煩,整體和微服務之間就不會有太大的區別,但每種架構的運營前景可能會截然不同。
容錯性設計
使用服務作為組件的一個結果在於應用需要有能容忍服務的故障的設計。任務服務可能因為供應商的不可靠而故障,客戶端需要盡可能的優化這種場景的響應。跟整體構架相比,這是一個缺點,因為它帶來的額外的復雜性。這將讓微服務團隊時刻的想到服務故障的情況下用戶的體驗。Netflix 的Simian Army可以為每個應用的服務及數據中心提供日常故障檢測和恢復。
這種產品中的自動化測試可以讓大部分的運維團隊正常的上下班。這並不意味着整體構架的應用沒有這么精巧的監控配置,只是在我們的經驗中它並不常見。
由於服務可以隨時故障,快速故障檢測,乃至,自動恢復變更非常重要。微服務應用把實時的監控放在應用的各個階段中,檢測構架元素(每秒數據庫的接收的請求數)和業務相關的指標(每分鍾接收的定單數)。監控系統可以提供一種早期故障告警系統,讓開發團隊跟進並調查。
這對於微服務架構尤其重要,因為微服務偏愛編排( choreography 協同工作;詳細定義的通用規則以保證協同不會導致混亂),事件之間的合作會導致緊急事件。許多專家稱贊這種緊急事件的價值,但事實是這種緊急事件有時是災難。監控是至關重要的,它能快速發現這種不良的緊急事件,讓我們迅速修復它。
整體架構,跟微服務一樣,在構建時是透明的,實情上,它們就是這樣子的。它們不同之處在於,你需要清楚的認識到不同進程間運行的服務是不相關的。庫對於同一進程是透明的,也因此不那么重要了。
微服務團隊期望清楚的監控和記錄每個服務的配置,比如使用儀表盤顯示上/下線狀態、各種運維和業務相關的指標。對斷路器(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來執行。
參考資料
- Martin Flower,Microservices
- infoQ,微服務架構解析
去中心化管理數據