微服務介紹

這 是一篇由 Chris Richardson 撰寫的客座文章。Chris 是 CloudFoundry.com 的創始人,這是一個早期的用於 Amazon EC2 的 Java PaaS (Platform-as-a-Service平臺即服務)。他如今爲大型組織提供諮詢服務,幫助他們提高開發和部署應用的能力。他還在有規律地寫關於微 服務的博客,博客地址:http://microservices.iohtml

==============nginx

目前,微服務獲得較多的關注:論文,博文,社交媒體上的討論,還有會議報告。他們處於指望膨脹期的頂峯,快速地向着登上 Gartner 趨勢報告前進。同時,在軟件社區還有一羣懷疑論者,他們無視微服務,認爲它沒什麼新意。反對派們聲稱,這種想法就是 SOA 的馬甲。可是,無論是大肆宣傳仍是懷疑主義,微服務架構模式具備明顯的好處——尤爲談到敏捷開發和複雜企業應用交付的時候。web

這篇博文是一個關於設計、構建和部署微服務的七部系列的第一部分。你將會了解到微服務的方法和它與傳統的單一架構模式的對比。這個系列將會詳細說明微服務架構的衆多元素。你將會了解到微服務架構模式的好處和缺點,對你的項目是否有意義,和怎樣應用它。數據庫

如今,咱們先看看爲何你應該考慮使用微服務。apache

構建總體應用

假設你想要構建一個全新的打車應用與 Uber 和 Hailo 競爭。通過了一些預備會議和需求收集以後,你將會手工建立一個新的工程,或者使用 Rails、Spring Boot、Play 或 Maven 這類工具生成一個。這個新應用將會有一個模塊化的六角形架構,就像下圖這樣:後端

Graph-01該應用的核心是服務模塊、域對象模塊和事件模塊實現的業務邏輯。圍繞在覈心周圍的是與外界交互的適配器。這些適配器包括數據庫訪問組件、生產和消費消息的消息傳遞組件、暴露 API 或實現 UI 的 web 組件。api

儘管具備合乎邏輯的模塊化架構,可是該應用作爲總體打包部署。具體的樣式依賴應用的語言和框架。例如許多Java應用打成WAR包,部署在Tomcat或 Jetty這樣的應用服務器。還有一些Java應用打成獨立可執行的JAR包。相似的,Rails和Node.js應用以目錄層次的形式打包。緩存

寫成這種形式的應用極其廣泛。它們很是易於開發,由於咱們的IDE和其餘工具專一於構建一個單獨的應用。這樣的應用一般也易於測試。經過簡單地運行 應用就能夠實現端到端的測試,使用Selenium就能夠測試UI。總體應用也易於部署。你僅僅須要複製打包的應用到服務器。你也能夠經過在負載均衡器後 面運行多個副本的方式擴展應用。在項目的早期階段,這種方式運做的很好。服務器

走向總體地獄(Monolithic Hell)

很不幸,這種簡單的方式有一個巨大的限制。成功的應用都會隨着時間增大,最終變得巨大。在每個衝刺(sprint),你的開發團隊實現了許多用戶故事,這固然意味着添加了許多行代碼。通過幾年以後,本來很小、很簡單的應用將會長成可怕的龐然大物。舉一個極端的例子,我最近與一個開發者進行了一次談話,他寫了一個工具分析他們數百萬行代碼的應用中的成千上萬個JAR包的依賴。我很肯定這樣一個怪獸是由大量的開發者通過數年的共同努力才製造出來的。網絡

一旦你的應用變成了一個複雜的龐然大物,你的開發團隊就可能生活在痛苦之中。敏捷開發的任未嘗試和交付將會舉步維艱。該應用的一個主要問題是過分地複雜。 它僅僅是太大了以致於任何一個開發者都不能完整地理解。所以正確地修復漏洞和實現新功能將會變得困難和耗時。更糟糕的是,這造成了一個惡性循環。若是基本 代碼難於理解,就很難作出正確的改動。那麼最終就會成爲一個可怕的、沒法理解的大泥球

應用程序的規模也會拖慢開發進度。應用程序的規模越大,啓動的時間越長。例如在最近的調查中,開發者表示啓動時間長達12分鐘。我也道聽途說過啓動時間長達40分鐘的應用程序。若是開發者不得不周期性重啓應用服務,那麼他們一天中很大一部分時間將浪費在等待上,他們的生產力將會受到影響。

巨大的、複雜的總體應用程序的另一個問題是它是持續部署的障礙。目前,SaaS應用一般在一天以內會屢次將改動推到生成環境。對於複雜的龐然大物,這極 其難處理,由於你必須從新部署整個應用來更新程序的任何一小部分。我前面提到的冗長的啓動時間也將產生不利的影響。並且由於改動的影響一般不能被充分的理 解,那麼你可能還必須作更普遍的手工測試。最終致使持續部署幾乎是不可能的。

當不一樣的模塊具備資源需求衝突的時候,總體應用程序也將難以擴展。例如,某個實現CPU密集型圖像處理邏輯的模塊很是適合部署在AWS EC2 Compute Optimized instances。另外某個內存數據庫的模塊最適合部署在 EC2 Memory-optimized instances。而後因爲這些模塊都得部署在一塊兒,因此你不得不在硬件的選擇上作出妥協。

總體應用程序的另一個問題是可靠性。由於全部的模塊都在同一進程內運行,因此任一模塊的漏洞,好比內存泄露,將會影響整個進程。此外,由於應用程序的全部實例是一致的,因此這些漏洞將會影響整個應用的可用性。.

最後但並不是不重要,總體應用程序使得采用新框架、新語言極其困難。舉個例子來講,假設你有兩百萬行使用XYZ框架寫的代碼。那麼使用新的ABC框架重寫整 個應用將會是極其昂貴的(不管是時間仍是花費),即便新框架至關的好。所以對於採用新技術,總體應用程序具備巨大的障礙。當你開始新的項目的時候,你將非 常糾結於選擇哪一種技術。

總而言之:你有一個已經長成可怕的龐然大物的,幾乎沒有開發者能夠理解的,成功的業務關鍵應用。這個應用程序使用過期的、沒有生產力的技術寫成,這使得招聘優秀的開發者變得很是困難。這個應用程序難以擴展並且不可靠。所以,敏捷開發和應用交付是不可能的。

因此你能怎麼辦呢?

微服務 – 處理複雜性

許多組織,好比Amazon、eBay和Netflix,已經採用如今被稱爲微服務架構模式的方法解決了這個問題。其想法是將應用程序分割成更小的相互關聯的服務,而不是構建單個可怕的總體應用程序。

一個服務一般實現一組獨立的特性或功能,好比訂單管理、客戶管理等。每一個微服務是一個具備六角形架構的迷你應用,其本身的六角形架構包含業務邏輯以及許多 適配器。某些微服務將會暴露供其餘微服務或者客戶端使用的API。另一些微服務可能實現web UI。在運行時,每一個實例一般是一個雲虛擬機或者一個Docker容器。

例如,前文所述的系統的一個可能的分解以下圖所示:

Graph-03

應用的每一個功能區域如今以微服務的方式實現。此外web應用程序分割成了一組更簡單的web應用程序(一個面向乘客的,一個面向司機的)。這使得更容易爲特定的用戶、設備或特定的用例部署單獨的服務。

每一個後端服務暴露一套 REST API,大部分服務調用其餘服務提供的 API。例如司機管理模塊使用通知服務告知空閒的司機可能的訂單。UI 服務調用其餘服務來渲染 web 頁面。服務也可能使用異步的、基於消息的通訊方式。服務間通訊將會在本系列後面的文章中詳細討論。

某些 REST API 是暴露給司機和乘客使用的移動 app 的。而後 app 不能直接訪問後端服務,其間的通訊是經過稱爲 API 網關的媒介傳遞的。API 網關負責負載均衡、緩存、訪問控制、API 測量和監控,該模塊可使用 NGINX 有效的實現。本系列後面的文章將會討論 API 網關。

Graph-05

微服務架構模式對應擴展立方體(Scale Cube)的 Y 軸擴展,擴展立方體是《The Art of Scalability》一書中描述可擴展性的 3D 模型。此外還有兩個擴展維度,X 軸擴展表示在負載均衡器後面運行多個相同的應用程序副本,Z 軸擴展(數據分割)表示使用請求中的某個屬性(例如數據表主鍵或用戶 id)來路由請求到特定服務器。

應用一般綜合使用三種擴展。Y 軸擴展分解應用程序到微服務,就像上圖展現的那樣。在運行時,爲了吞吐量和可用性,X 軸擴展在負載均衡器後面運行多個服務的實例。某些應用也可能使用 Z 軸擴展分割服務。下圖展現瞭如何使用 Docker 將訂單管理服務部署在 AWS EC2 上。

 

Graph-02

在運行時,訂單管理服務包含多個服務實例。每一個服務實例是一個 Docker 容器。爲了高可用性,這些容器運行在多個雲虛擬機上。在這些服務實例前面是一個諸如 NGINX 這樣的負載均衡器在多個實例之間分發請求。負載均衡器也可能處理一些別的事情,好比緩存訪問控制API 測量監控

微服務架構模式顯著地影響了應用程序與數據庫之間的關係。每一個服務有本身的數據庫模式,而不是共享單個數據庫模式。儘管這種方式與企業級數據模型的 想法相悖,也會形成某些數據的冗餘。可是若是你想得到微服務的好處,那麼每一個服務一個數據庫模式是很關鍵的,由於這確保了鬆散耦合。下圖展現了應用的數據 庫架構。

Graph-04

每一個服務有其本身的數據庫。那麼服務就能夠選擇使用最符合需求的數據庫,這就是所謂的混合持久化架構。例如查找乘客附近司機的司機管理模塊必須使用支持高效地理查詢的數據庫。

表面上微服務架構模式相似於 SOA。這兩種架構都包含一組服務。你能夠認爲微服務架構模式就是不包括商業化和 Web 服務規範(WS-)、企業服務總線(ESB)的 SOA。基於微服務的應用傾向於使用更簡單輕量級的協議,好比 REST 而不是 WS-。很大程度上也避免使用 ESB,取而代之的是使用微服務本身實現相似 ESB 的功能。微服務架構模式也拒絕 SOA 的其餘部分,好比規範模式的概念。

微服務的好處

微服務架構模式有許多重要的好處。第一,它解決了複雜性的問題。它將一個可怕的、龐大的總體應用分解成一組服務。在總體的功能沒有改變的同時,應用 程序已經被分解成可管理的模塊或服務。每一個服務有以 RPC 或者消息驅動 API 形式定義清楚的界限。微服務架構模式增強了必定程度的模塊化,這在總體應用程序中是很難實現的。所以單個的服務能夠更快的開發,更簡單的理解和維護。

第二,這種架構使得每一個服務能夠由單獨的團隊獨立開發,這些團隊能夠專一於某個服務。開發者能夠自由地選擇合理的技術,只要服務遵照 API 約定便可。固然大部分組織想要避免混亂地徹底無限制的技術選項。而後這種自由意味着開發者不在受限於使用可能過期的技術開始新的項目。當開始寫一個新服務 的時候,他們能夠選擇使用當前的技術。並且由於服務相對較小,因此使用當前的技術重寫老服務是可行的。

第三,微服務架構模式使得每個微服務能被獨立部署。開發者不再須要調整本地對其服務的更變 而進行部署。各類類型的變動能在他們測試時當即部署。UI 團隊也能夠這樣作,舉例來講,當 UI 發生改變時,能執行 A|B 測試並快速迭代。微服務架構模式讓持續部署成爲可能。

最後,微服務架構模式使得每個服務均可以被獨立擴展。你能夠部署大量剛好符合要求容量和有效約束條件的服務實例。此外,你可使用最匹配服務資源 要求的硬件。例如,你能夠在計算優化過的 EC2上部署一個密集CPU 鏡像處理服務實例,還能夠在內存優化的 EC2 上部署內存數據庫服務實例。

微服務的缺點

就像 Fred Brooks 在30年前說的,沒有銀彈。跟別的技術同樣,微服務架構也有缺點。其中的一個缺點就是名字自己。微服務這個詞過度強調服務的規模。實際上有些開發者支持構 建極其細粒度10-100 LOC 的服務。儘管規模小的服務更可取,可是最好記住這只是手段而不是目的。微服務的目的是充分地分解應用程序以促進敏捷開發和部署。

微服務另一個主要的缺點是微服務應用作爲分佈式系統帶來的複雜性。開發者須要選擇或者實現基於消息或 RPC 的進程間通訊機制。並且必須編寫處理部分失敗的代碼,由於請求的目的地可能很慢或者不可用。雖然這都不是高深莫測的事情,可是相對於總體應用程序這明顯更 複雜,由於總體應用程序中模塊間的調用是經過語言層面的方法/程序調用實現的。

微服務的另一個挑戰是分割的數據庫架構。更新多個業務實體的事務至關廣泛。這種事務在總體應用程序中很容易實現,由於只有一個數據庫。而後在基於微服務的應用中,你須要更新多個屬於不一樣服務的數據庫。分佈式事務一般不是最好的選擇,不只僅由於 CAP 理論,並且目前許多高擴展性的 NoSQL 數據庫和消息代理就不支持。你最終不得不使用基於最終一致性的方法,這對於開發者來講更具挑戰性。

測試微服務也很複雜。使用 Spring Boot 這樣的現代框架很容易開始一個總體 web 應用程序,編寫測試類測試其 REST API。於此相反,對於微服務的一個相似的測試則須要運行該服務以及依賴的服務(或者至少須要配置那些服務的存根)。這也不是高深莫測的事情,可是不要低 估作這些事情的複雜性。

微服務架構模式另一個主要的挑戰是實現跨服務的需求變動。設想你實現的用戶故事須要更改服務 A,由於 A 依賴 B,B 依賴 C,因此你又得更改服務 B 和 C。在總體應用中,你能夠簡單地更改對應的模塊,集成這些變動一塊兒部署。相反在微服務架構模式中,你須要仔細計劃和協調各個服務的更改上線。例如你須要首 先更新服務 C,接着是服務 B,最後纔是服務 A。很幸運的是大部分改動一般隻影響一個服務,須要協調的跨服務更改相對較少。

部署一個基於微服務的應用也很複雜。總體應用程序簡單地部署在一組相同的服務器上,在這些服務器前面是一個傳統的負載均衡器。每一個應用程序實例配置好基礎設施服務的位置(主機和端口),例如數據庫和消息代理。相反微服務應用一般包含大量服務。例如 Hailo 有160個不一樣的服務Adrian Cockcroft 聲 稱 Netflix 有超過600個服務。每一個服務有多個運行實例。有太多運行的實例須要配置、部署、擴展和監控。另外你也須要實現一個服務發現機制(這將會在後面的文章討 論)以確保某服務能夠找到須要通訊的其餘服務的位置(主機和端口)。傳統的麻煩的基於票據的手工配置方式沒法處理這個層次的複雜性。所以成功的部署微服務 應用須要開發者對部署方法有更強的控制,已經更高水平的自動化。

自動化的一個方法是使用現成的 PaaS,好比 Cloud Foundry。PaaS 爲開發者提供了一種簡單的方式部署和管理微服務。PaaS 可使開發者沒必要考慮採購和配置 IT 資源的問題。同時,配置 PaaS 的系統和網絡專家能夠確保符合最佳實踐知足公司的需求。另一種自動化微服務部署的方式本質上就是開發本身的 PaaS。這一般是從使用某個集羣解決方案開始的,好比結合 Docker 這類技術的 Mesos 或Kubernetes。在本系列的後續文章中咱們將會看到基於軟件的應用交付方法如何解決這個問題,好比NGINX,能夠很容易地處理微服務層面的緩存、訪問控制、API 測量和監控。

總結

構建複雜的應用自己就很難。總體架構只適合簡單的輕量級應用。對於複雜的應用,若是你選用總體架構,那麼最終你會生活在痛苦之中。微服務架構對於複雜的、演化的應用是更好的選擇,儘管微服務架構有些缺點和實現上的挑戰。

在以後的文章中,我將會深刻微服務架構模式的各個方面,探討服務發現、服務部署、總體應用程序重構策略這些主題。

請繼續關注…

來源:http://www.oschina.net/translate/introduction-to-microservices

本文爲轉載,如需再次轉載,請查看源站 「oschina.net」 的要求。若是咱們的工做有侵犯到您的權益,請及時聯繫咱們。 

相關文章
相關標籤/搜索