微服務

——Martin FowlerJames Lewis

原文

微服務

新的架構術語——微服務

在過去的幾年興起了一個新的架構術語——微服務。它用來描述將軟件應用程序設計為一組可以獨立部署的服務的特定方法。這種架構風格雖然沒有明確的定義,但是其從組織,業務功能方面呈現出一些共同特征:自動化部署,端點智能化,語言和數據去中心化管理。

微服務——在紛繁復雜的軟件架構領域出現的又一新名詞。雖然我們的本能反應是對此類事物不屑一顧。但是,我們發現,微服務描述的軟件系統風格越來越具有吸引力。我們看到在過去的幾年里許多項目采用了這種風格,并且到目前為止效果是積極的。甚至,對于我許多同事來說,這已經成為構建企業級應用的首選風格。然而遺憾的是,沒有太多的關于概述什么是微服務風格以及如何使用微服務的信息。

簡單來說,微服務架構風格是一種把單個應用系統劃分成一套小的服務來進行開發,每個服務擁有自己的進程, 彼此使用輕量級的機制,如HTTP資源API,進行通信,這些服務圍繞業務功能構建,通過全自動化部署設施進行獨立部署,對它們盡可能的分散管理,可以為它們選擇不同的開發語言,選擇不同的數據存儲技術存儲數據。

和單體風格——使用單個單元構建單體應用的方法——進行比較有助于對微服務風格的說明。企業級應用通常由三個部分構成:客戶端UI(由運行在客戶端瀏覽器里的HTML頁面和腳本組成)、數據庫(有許多插入到通用的,通常是關系型的DBMS的表組成)、服務端應用。服務端應用處理HTTP請求,執行域邏輯,返回或更新數據庫數據以及選擇并構建HTML視圖發送給瀏覽器。服務端應用是一個單體——一個單一的邏輯執行體。任何對系統的改變都需要為服務端應用編譯并部署一個新的版本。

這樣的單體服務器是構建系統的自然而然的方法。你處理請求的所有邏輯都運行在單個進程中。同時它允許你依靠編程語言的基本特性把應用程序拆分成類、函數和命名空間等。需要注意的是,你可以在開發機器上運行并測試應用,使用部署管道確保對應用的修改經過適當的測試然后部署到生產環境。你可以在一個負載均衡后面運行多個這樣的單體應用實例來實現水平擴展。

單體應用可以成功,但人們也越來越對其感到沮喪,尤其是當更多的應用部署到云上的時候。(應用各部分的的)變更周期被捆綁在一起——對應用一個小的部分的修改都要求整個應用重新構建和部署。隨著時間的推移,單體應用通常也很難維持一個好的模塊化結構,很難做到一個本來僅影響一個模塊的變更只需要修改這個模塊就行(注:也就是說:本來一個變更業務上看上去只需要修改某個模塊,但事實上,由于隨著時間的推移,系統漸漸"腐敗",模塊間耦合增加,導致需要修改其他的模塊。)。擴展也只能就整個應用而不是應用的的某個部分進行,從而導致消耗更多資源。


Figure 1: Monoliths and Microservices

上述單體應用帶來的困擾促使微服務架構風格的出現——用一組服務來構建應用系統。每個服務可以獨立部署和伸縮,每個服務都提供固定的模塊邊界,不同的服務甚至允許使用不同的編程語言來編寫。而且不同的服務可以由不同的團隊來管理。

我們不會說微服務風格是一種新穎的風格或創新,因為它的根源至少可以追溯到Unix設計之道。然而,我們認為沒有足夠多的人在考慮使用微服務架構。我們認為如果使用微服務架構,軟件開發會變得更好。

微服務架構特征

我們不說存在一個對微服務架構風格的正式定義。然而我們可以嘗試描述下我們所看到的符合這種架構風格的共同特征。與任何概括共同特征的定義一樣,不是所有的微服務架構都具有所有的特征。但是我們希望大多數微服務架構都具有大多數的特征。雖然我們這些作者已經是這個相當寬松的社區的積極分子,但我們的目的還是想描述在我們自己的工作中和我們所了解的團隊做出的類似的努力中所看到的東西。不過,我們不會做出什么是符合微服務架構的定義。

組件服務化

在軟件行業,我們一直希望通過把組件組裝在一起的方式來構建系統。就像我們看到的物理世界許多創造事物的方式一樣。在過去幾十年里,我們看到了作為大多數語言平臺一部分的大量的公共庫的顯著發展。

當我們談論組件的時候會碰到一個難于定義的問題,就是組件是什么?我們的定義是,組件是一個可獨立替換和升級的軟件單元。

微服務架構會使用庫,但它實現組件化的主要方式是把系統拆分成服務。我們定義的是可以鏈接到程序并在內存中被函數調用的組件,而服務則是通過Web服務請求或者RPC之類的機制進行通信的進程外的組件。(這和許多使用OO方法設計的程序里的服務對象是不同的概念)。

使用服務而不是庫作為組件的一個主要原因是服務是可獨立部署的。如果你有一個由位于單個進程里的多個庫組成的應用程序,那么對于任何一個庫的修改都會導致整個應用程序的重新部署。然而,如果應用程序被分解成多個服務,那么你就可以做到許多針對單個服務的修改僅需要重新部署該服務本身。這不是絕對的,有些變更會改變服務接口,這會導致一些協調的發生(注:受影響的服務需要調整接口的調用)。但一個好的微服務架構的目標就是通過內聚的服務邊界和服務契約機制的演進讓影響最小化。

使用服務化組件另外一個結果是組件接口變得更清晰。許多語言沒有一個良好的機制來定義一個清晰的可發布接口。 通常我們僅通過文檔和規則來防止客戶破壞組件的封裝,這導致組件間過度緊密耦合。服務間通過明確的RPC機制進行可以更容易避免這種情況發生。

但這也有缺點。RPC比進程內調用昂貴,而且這種RPC只能是粗粒度的,這往往導致使用起來比較笨拙。如果你需要改變組件間的職責分配,那么跨進程邊界的行為遷移將更困難。

咋一看,我們發現服務就是對應運行時進程,但這僅僅是表象。一個服務可以由多個總是一起開發和部署的進程組成。比如一個服務有一個應用進程和僅被該服務使用的數據庫。

按業務功能劃分組織

當要拆分一個大的應用的時候,通常管理層主要從技術層面著手,從而會產生UI團隊、服務端邏輯團隊和數據庫團隊。當團隊是這樣劃分的時候,即使一個簡單的變更也會導致跨團隊進行時間估計和預算審批。"機靈"的團隊為了他們自己的便利會兩害相權取其輕——強制把邏輯放在他們能訪問的應用之中。換句話說,邏輯將無處不在(注:大家為了避免跨團隊溝通的麻煩,盡可能的在自己可控的范圍內注入業務邏輯,導致“邏輯無處不在”,同時因為不會優先考慮系統模塊高內聚和低耦合,導致系統“腐化“)。下面是一個康威定律的例子。

任何設計系統(廣義上定義的)的組織設計出來的系統,其結構都將和組織溝通結構一致。

——Melvyn Conway, 1967

Figure 2: Conway's Law in action

微服務拆分的方法是不同的,拆分的服務是按照業務功能(業務面)來劃分的。這樣的服務需要為其業務功能完成全棧的軟件實現,包括UI,持久存儲及所有的外部協作。因此,(實現服務的)團隊也需要是跨功能的團隊,需要擁有開發所需的,如用戶體驗,數據庫和項目管理等完整的技能。


Figure 3: Service boundaries reinforced by team boundaries

www.comparethemarket.com是這種組織的一家公司。跨功能團隊負責構建和營運每個產品,每個產品被劃分成多個獨立的服務,服務間使用消息總線通信。

大型單體應用也總是能夠按業務功能進行模塊化,雖然這種情況不常見。當然我們會力促一個構建單體應用的大型團隊按業務線拆分自己。我們在這里看到的主要問題是:他們往往是圍繞太多的上下文來組織的。假如單體應用橫跨許多這樣的模塊化的邊界,對團隊的個體來說是很難短期記住這些模塊的。并且,我們看到那些模塊化的邊線要求遵守大量的規則。組件服務化所必然要求更明確的分隔,這使得保持清晰的團隊邊界更容易。

產品而非項目

我們看到,大多數應用開發工作使用項目模式,其目標是發布一些被認為完成的軟件。軟件完工后被移交給運維部門,然后項目團隊解散。

微服務支持者傾向于避免這種模式,而是秉承一種團隊應該擁有整個產品的生命周期的理念。對這種理念的共同啟發是來自亞馬遜的“你構建,你運行”的理念。開發團隊負責生產環境的軟件,這使得開發人員能夠和生產環境里的軟件保持日常的聯系,同時也增進開發人員和客戶之間的聯系,因為他們至少要承擔一些客戶支持的工作。

產品心態與業務功能緊密相連。它與把軟件看作一套(需要開發)完成的功能不同,它是一種持續的關系——軟件如何幫助用戶提高業務能力。

沒有理由解釋相同的做法(注:產品心態)為什么不能應用到單體應用 。不過更小粒度的服務更易于建立服務開發者和用戶之間的人際關系。

智能端點和啞管道

當在構建不同進程間的通信結構的時候,我們看到許多產品和方法強調把重要的處理放到通信機制本身里面。一個很好的例子就是企業服務總線(ESB)。ESB產品通常會包含復雜的設施用于消息路由,編排和轉換,以及業務規則應用。

但微服務社區更偏好另外一個方法:智能端點和啞管道。微服務構建應用程序以高內聚低耦合為目標。他們擁有自己的域邏輯,扮演著更像經典Unix風格的過濾器(filter)角色,接受請求,然后執行相應的邏輯,最后產生應答。這是通過簡單的RESTful協議進行編排,而不是如WS-Choreography 和BPEL等復雜協議或者中心化工具編排。

使用最廣泛的兩個協議是HTTP請求/應答資源API和輕量消息。對前者最恰當的描述是:

是web,而不是位于web之后

——Ian Robinson

微服務團隊使用萬維網(更大程度上是Unix)相關的協議和原則。對開發和運維來說,經常使用的資源可以毫不費力的緩存起來。

第二個普遍方法是使用輕量的消息總線發布消息。所選擇的基礎架構典型的是啞的(僅僅是在扮演消息路由)——簡單的實現,如RabbitMQ或者ZeroMQ,它們僅提供可靠異步管道。其他的處理仍然位于產生或消費消息的服務端點中。

在單體應用中,組件在進程內執行,通過方法或函數調用進行通信。把單體應用改變成微服務最大的問題在于改變通信方式。直接把內存中的方法調用轉換成RPC會導致通信的繁瑣且無法順利執行。因此,你需要把這種細粒度的通信(函數調用)替換成粗粒度通信。

(注:智能終端,啞管道是相對類似基于ESB構建起來的SOA中的啞終端,智能管道而言的。隨著微服務架構的出現,基于K8s+Service Mesh的服務網格系統,已經演變成了智能平臺和聚焦業務邏輯的智能服務。如下圖所示:


SOA vs MSA vs CNA

去中心化治理

中心化管治的結果最終都傾向于形成單一技術平臺的標準化。經驗表明這會造成一些局限性——不是每個問題都是釘子,也不是每個方案都是錘子(注:也就是說單一的方案不能解決所有的問題)。我們更喜歡使用合適的工具來完成相應的工作。雖然單體應用也可以一定程度上獲得使用不同開發語言的好處,但這并不普遍。

把單體應用拆分成服務之后,我們就可以選擇不同的開發語言來構建這些服務。你想使用Node.js起來一個簡單的報表頁面嗎?去弄吧。你想使用C++寫一個特別簡單的且近乎實時的組件嗎?好,沒問題。你想變換不同風格的數據庫來更好地適應組件的讀取行為嗎?我們有那種技術來重建它。

當然,只是因為你能夠這樣做,但并不意味著你應該這樣做——你有這樣的選項來分割你的系統。

構建微服務的團隊也喜歡使用不同標準化的方法。不像把一套定義好的標準寫在紙上,他們更喜歡這樣的理念:創造有用的工具,其他的開發者也可以用來解決他們遇到的類似問題。這些工具從實現代碼中收集而來,并分享給更廣泛的團隊。有時會以但不限于內部開源的方式使用。如今git和github已經成為版本控制系統的事實上的選擇,在公司內部的開源實踐已經變得越來越普遍了。

Netflix是奉行這種哲學的組織的一個好例子。分享有用的,重要的是經過實戰驗證的代碼庫會鼓勵其他開發者以類似的方式解決相似的問題,然而,如果需要也可以選擇不同的方法。這些共享庫傾向于解決數據存儲和進程間通信等公共問題,也包括下面我們要進一步討論的基礎架構自動化。

對于微服務社區來說,(對服務契約的)日常管理(overhead)尤其不受青睞。這不是說,社區不認為服務契約具有價值。恰恰相反,往往是因為認為它們更具價值,所以,他們在尋找管理這些契約的不同方法。如Tolerant Reader消費者驅動型契約模式經常應用到微服務。這些模式有助于服務契約獨立進化。作為構建的一部分,執行消費者驅動型契約,可以增加你的信心,為你的服務是否工作提供快速反饋。實際上,我們知道有一家澳大利亞的團隊使用消費者驅動契約來驅動構建新的服務。他們使用簡單的工具來定義服務契約。這成為新服務在編碼之前的自動構建的一部分。隨后服務實現僅需要滿足這些契約就可以。這是一種優雅的方法,以此可以避免構建新的軟件時遇到“YAGNI”的困境。這些技術和圍繞這些技術出現的工具降低了服務間一時的耦合,減少了中心化契約管理的需求。

也許去中心化管治的最高境界就是亞馬遜所宣揚的“構建并運行它”的理念。團隊對構建的軟件的方方面面負責,包括7X24小時運維。這種級別職責的下放絕對不是慣常做法,但我們確實看到越來越多的公司把這些職責賦予開發團隊。Netflix是采用這種理念的組織。被自己寫的頁面凌晨3點喊醒必然促使你關注自己代碼的質量。傳統中心化管治模式與這種思想卻相去甚遠。

去中心化數據管理

去中心化數據管理以許多不同的方式存在。從最高的抽象級別來看,它意味著世界的概念模型在不同的系統之間是不同的。當在大型企業集成時,這是一個常見的問題。客戶銷售試圖將會與(系統)支持視圖不同。銷售視圖中所謂的客戶可能根本就不會出現在(系統)支持視圖里。即使出現夜可能具有不同的屬性,或者(更糟糕的)屬性相同,但語義卻有細微的差別。

這種情況在不同的應用之間是常見,但也可能出現在一個應用的內部,特別是當應用被拆分成單獨的的組件的時候。考慮此問題的一個有用的方式是領域驅動設計(DDD)中的界限上下文概念。DDD將一個復雜的域分解成多個有邊界的上下文,并在它們之間建立映射關系。這個過程對建立單體應用和微服務架構應用都是有用的,但服務和使其更清晰的上下文邊界之間確實存在自然的關聯,而且像我們在業務功能那節討論的一樣這種關聯得以增強。(注:服務是按照有上下文邊界的業務面來劃分的,所以服務邊界自然清晰。)

除了概念模型去中心化,微服務的數據存儲也可以去中心化。單體應用偏向于使用單一邏輯數據庫實現數據持久化,企業通常也偏向于所有應用使用一個單一的數據庫——許多這些決定是基于供應商的商業許可模式做出的。微服務則偏好于讓每個服務管理它自己的數據庫,可以是相同數據庫的不同實例,也可以是完全不同的數據庫——這種方法叫作“復式持久化”(Polyglot Persistence)。你可以在單體應用中使用這種數據持久化方法,但微服務中使用更多。


跨微服務的數據職責去中心化也意味著數據更新的管理。處理數據更新的常用方法就是要使用事務保證多個資源的一致性。這個方法經常在單體應用中使用。

這樣使用事務有助于保持一致性,但產生臨時耦合,這在跨多個服務時是有問題的。眾所周知,分布式事務是不易于實現的。作為微服務架構的一個結果,就是強調服務間無事務協作。作為一個明確的共識就是,一致性僅僅是最終一致性,中間出現的問題由一些補償操作來處理。

選擇以這種方式來管理不一致性對許多開發團隊來說是一個挑戰,但它往往和業務實踐是相似的。業務常常會運用一定程度的不一致性來快速響應需求,而使用某種逆向過程來應對錯誤(注:如事務回滾)。只要修正錯誤的成本小于保持更高一致性情況下業務損失的成本,這種權衡之計就是值得的。

基礎架構自動化

基礎架構自動化技術在過去的幾年取得了極大的進步——隨著云計算的發展,尤其是AWS,其從構建、部署到運維微服務的復雜度都得到了降低。

許多使用微服務架構的產品和系統都是由在持續部署以及它的前導持續集成方面經驗豐富的團隊構建。使用這種方式構建軟件的團隊廣泛使用基礎架構自動化技術。下圖描述了一個構建管道。


Figure 5: basic build pipeline

由于這里不是介紹持續發布的文章,所以我們只在這里關注下幾個關鍵特性。 我們想獲得盡可能多的自信,我們的軟件可以工作,為此我們運行許多自動化測試。 把工作的軟件送入這個構建管道就意味著自動部署到新的環境。

單體應用將被相當愉快的構建、測試以及通過這些環境(注:如上圖所示,集成測試環境、UAT環境和性能測試環境)。事實證明一旦你投資部署單一應用的到生產環境的管道自動化,那么部署更多的應用似乎不再那么恐怖。記住,持續部署的目的之一就是使得部署過程變得無趣,所以,不管一個還是三個應用程序,只要部署過程仍然是無趣,那就無所謂。

另外一個我們看到團隊大量使用基礎架構自動化的領域是生產環境的微服務管理。我們上面斷言只要部署是無聊的,那么單體和微服務部署沒什么不同,但相反,各自運維視覺完全不同。


Figure 6: Module deployment often differs


容錯設計

使用服務作為組件的一個結果是應用程序需要設計能夠容忍服務的失敗。任何服務的調用都有可能因為服務無效而失敗。客戶端需要盡可能優雅的應對此情況。這相比單體設計是一個缺點,因為它為了處理服務調用失敗而引入額外的復雜性。這也導致微服務團隊不斷的考量服務的失敗如何影響用戶的體驗。Netflix的Simian Army在工作日引發服務甚至數據中心故障來測試應用程序彈性和對其監控。

這種生產環境的自動化測試足夠讓大多數運維團隊在開始休假一周前就趕到膽戰心驚。這不是說單體架構風格不能做復雜的監控設置,只是在我們所經歷的里頭比較少見。

因為服務可能在任何時候都會發生故障,所以迅速的發現故障,如果可能,自動恢復服務就顯得很重要了。微服務應用非常重視監控,包括架構層面的指標監控(比如,每秒有多少讀數據庫的請求(rps))和業務相關的指標監控(比如,每分鐘收到多少訂單)。語義上的監控可以提供一個警報系統,顯示什么情況正在變得糟糕,從而驅動開發團隊進行跟進和調查。

這對微服務架構尤其重要,因為微服務對編排和“事件協作”的偏好可能會導致意外的行為。雖然許多權威專家盛贊意外收獲的價值,但事實上,意外行為有時候可能是壞事。監控對迅速發現意外情況并處理至關重要。

單體應用可以和微服務一樣透明的構建——事實上也應該這樣。不同的是,你必須要知道運行在不同的進程里的服務什么時候連接斷開了。但這種透明對于同一個進程里頭的庫來說基本沒什么意義。

微服務團隊期待看到對每個獨立的微服務的細致的監控和日志設置,比如顯示開關狀態和各種運維及業務相關指標的儀表盤。另外像我們日常遇到的例子,如關于斷路器,當前吞吐量和延遲的詳細信息。

演進式設計

微服務的實踐者通常都具有演進式設計的背景,把服務分解看作是一個長遠的工具,幫助應用程序開發者在不減緩應用程序的變化速度的同時控制變化。控制變化不是必須抑制變化——有正確的態度,好的工具,你能夠使得軟件頻繁快速的變化,并使其得到良好的控制。

無論你什么時候想把軟件系統拆分成組件,你都會面臨如何拆分的問題——我們應該遵循什么原則來切分我們的應用? 組件的一個關鍵屬性是關于獨立替換和可升級的概念——這意味著,我們要尋找一個點,我們可以想象,在這個點的代碼可以重寫但不會影響它的協作者。實際上,許多微服務團隊考慮的更多,他們明確的期望許多服務可以被廢棄而不是長期演進(注:也就是這個服務不僅可以獨立重寫,替換,甚至可以拋棄而不會影響其他的部分)。

Guadian網站是一個很好的例子,它被設計和構建成了一個單體系統,但在朝微服務方向演進。單體仍然是這個網站的核心。不過他們更喜歡使用微服務增加新的功能,這些微服務調用單體的API. 這種方法對于提供本質上是臨時性的功能,比如體育賽事相關的頁面尤其便利。作為網站一部分的這種功能可以使用快速開發語言迅速的組織在一起,一旦賽事結束就移除掉。我們在金融機構也看到了類似的處理,一個新的服務因市場機遇被創建加入系統,幾個月甚或幾周后就撤掉。

強調可替換性是更通用的模塊化設計原則的一個特例,通過變化模式驅動模塊化(注:Kent Beck在《Implementation Patterns》中提到的變更速率原則——變更速率相同的數據和邏輯放在一塊,而不同的要分開)。你要把在同一時間變化的東西放在同一個模塊里。很少變化的系統部分應該和當前不斷變化的部分處于不同的服務里。假如你發現自己在不斷重復的同時修改兩個服務,那么意味著這兩個服務應該合并。

以服務的方式構建組件使得可以制定更加細粒度的發布計劃。單體應用的任何變更要求整個應用的完全重新構建和部署。然而,使用微服務,你只需要重新部署你修改的服務。 這可以簡化并加速發布過程。確定就是你不得不關心對服務的變更是否會影響它的使用者。傳統的集成使用版本化來應對這個問題。但是在微服務的世界里更偏向于把版本化作為最后的手段。我們可以把服務設計對它所以依賴的服務的變化盡可能的容錯來避免大量的版本化。

微服務是未來嗎?

撰寫該文的主要目的是闡述微服務的主要思想和原則。這同時讓我們更清楚的認識到微服務架構風格是一個重要的思想——值得為企業級應用認真考慮。我們目前構建了數個此類風格的系統,也知道一些公司在使用和喜好這種構建服務的方法。

我們了解在某種程度上作為推動這種架構風格的先鋒包括:亞馬遜、Netflix、Guardian、英國政府數字化服務、realestate.com.au、 前進報(Forward)以及comparethemarket.com。 2013的巡回大會上有很多轉向使用類似微服務的如Travis CI的東西的公司的例子。同時,也有許多組織長期在做的事情,我們把它們歸類為微服務,只是沒有叫這個名字而已(通常會打上SOA的標簽——盡管,如我們所說,SOA以很多相互矛盾形式存在)。

然而,盡管有這些積極的經驗,但我們并不確定微服務就是未來軟件架構的方向。雖然到目前為止我們所遇到的(微服務架構方面的情況)相對于單體應用來說都是正面的,但我們也清楚這樣一個事實:那就是我們所以經歷的時間還是不夠,以至于無法做出處充分的判斷。

往往,只有在你做出了架構決策幾年后其真正的結果才足以顯現出來(注:證明當初決策是對還是錯)。我們看到的項目,有一個好的團隊,帶有很強的模塊化意念,可構建的單體架構多年來已經腐朽了(注:模塊化邊界變得模糊,耦合度升高,內聚度降低)。許多人認為這種腐朽在微服務里頭是幾乎不可能發生的,應為服務的邊界是清晰的,難以遮掩的。然而,除非我們看到足夠多經年的系統,否則我們無法真正評估微服務架構成熟度。

當然,人們有理由預料到微服務不會成熟的很好。對于組件化的任何努力,其成功在于如何使得組件很好的適配軟件。準確的找出組件的邊界應該位于哪里是很困難的。演化式設計意識到正確獲取邊界的困難和重構的重要性。但是當你的組件服務是使用遠程通信時,重構它們會比重構進程內的庫更加困難:代碼跨服務邊界移動是困難的,接口的變更需要參與者調整,需要增加向后兼容層,測試也會變得更加復雜。

另外一個問題就是假如你沒有清晰的設計好組件,那么你所做的其實就是把復雜性從組件內部轉移到了組件之間的連接上。這不僅僅把復雜性轉移了,而且還轉移到了模糊及難以控制的地方。當看著小且簡單的組件內部,而且組件間也沒有繁雜的連接,那么你很容易相信事情會變得更好。

最后,團隊技能因素。新的技術易于被技能更好的團隊采用。 但在高技能的團隊使用的高效技術在低技能團隊不一定湊效。我們見過大量的例子,低技能團隊構建混亂的單體架構。不過要知道這種混亂發生在微服務架構里會出現什么情還需要時間。糟糕的團隊總是創建糟糕的系統——很難判斷微服務是否減少了這種情況下的混亂,還是使它變得更糟。

我們聽到的一個合理的觀點是你一開始不應該使用微服務架構,而是單體架構,同時保持模塊化, 然后一旦單體變得有問題時拆分成微服務。(雖然這個建議不是很理想,因為好的進程間接口通常并不一定是好的服務接口。)

所以我們謹慎樂觀的說:到目前為止,根據看到的足夠多的關于微服務的信息,我們認為微服務是一個值得嘗試的方向。我們不能確定最終如何,但軟件開發的挑戰之一就是你只能僅僅憑你目前能獲取的不完善的信息來做出決定。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容