微服務是一種架構風格,它要求咱們在開發一個應用的時候,這個應用必須構建成一系列小服務的組合;node
能夠經過http的方式進行互通。web
要說微服務架構,先了解一下之前的單體應用架構數據庫
所謂單體應用架構是指,咱們將一個應用的中的全部應用服務都封裝在一個應用中。服務器
不管是ERP、CRM或是其餘什麼系統,你都把數據庫訪問,web訪問,等等各個功能放到一個war包內。網絡
這樣作的好處是,易於開發和測試;也十分方便部署;當須要擴展時,只須要將war複製多份,而後放到多個服務器上,再作個負載均衡就能夠了。架構
單體應用架構的缺點是,哪怕我要修改一個很是小的地方,我都須要停掉整個服務,從新打包、部署這個應用war包。特別是對於一個大型應用,咱們不可能吧全部內容都放在一個應用裏面,咱們如何維護、如何分工合做都是問題。負載均衡
一旦您的應用程序成爲了一個龐大、複雜的單體,您的開發組織可能會陷入了一個痛苦的境地,敏捷開發和交付的任何一次嘗試都將原地徘徊。一個主要問題是應用程序實在很是複雜。對於任何一個開發人員來講顯得過於龐大.複雜的單體應用自己就是持續部署的障礙,當不一樣模塊存在資源需求衝突時,單體應用可能難以擴展框架
單體應用的架構方式,咱們把全部的功能單元放在一個應用裏面。而後咱們把整個應用部署到服務器上。若是負載能力不行,咱們將整個應用進行水平復制,進行擴展,而後在負載均衡。異步
所謂微服務架構,就是打破以前單體架構方式,把每一個功能元素獨立出來。把獨立出來的功能元素的動態組合,須要的功能元素纔去拿來組合,須要多一些時能夠整合多個功能元素。因此微服務架構是對功能元素進行復制,而沒有對整個應用進行復制。分佈式
這樣作的好處是:
(1)節省了調用資源。
(2)每一個功能元素的服務都是一個可替換的、可獨立升級的軟件代碼。
微服務架構模式相似於 SOA。微服務是由一組服務組成。然而,換另外一種方式去思考微服務架構模式,它是沒有商業化的 SOA,沒有集成 Web 服務規範 (WS-) 和企業服務總線 (Enterprise Service Bus, ESB) 。基於微服務的應用支持更簡單、輕量級的協議,例如,REST,而不是 WS-。他們也儘可能避免使用 ESB,而是實現微服務自己具備相似 ESB 的功能。微服務架構也拒絕了 SOA 的其餘部分,例如,數據訪問規範模式概念。
微服務架構模式有許多很是好的地方。
第一,它解決了複雜問題。它把可能會變得龐大的單體應用程序分解成一套服務。雖然功能數量不變,可是應用程序已經被分解成可管理的塊或者服務。每一個服務都有一個明肯定義邊界的方式,如遠程過程調用(RPC)驅動或消息驅動 API。微服務架構模式強制必定程度的模塊化,實際上,使用單體代碼來實現是極其困難的。所以,使用微服務架構模式,個體服務能被更快地開發,並更容易理解與維護。
第二,這種架構使得每一個服務均可以由一個團隊獨立專一開發。開發者能夠自由選擇任何符合服務 API 契約的技術。固然,更多的組織是但願經過技術選型限制來避免徹底混亂的狀態。然而,這種自由意味着開發人員再也不有可能在這種自由的新項目開始時使用過期的技術。當編寫一個新服務時,他們能夠選擇當前的技術。此外,因爲服務較小,使用當前技術重寫舊服務將變得更加可行。
第三,微服務架構模式能夠實現每一個微服務獨立部署。開發人員根本不須要去協調部署本地變動到服務。這些變動一經測試便可當即部署。好比,UI 團隊能夠執行 A|B 測試,並快速迭代 UI 變動。微服務架構模式使得持續部署成爲可能。
最後,微服務架構模式使得每一個服務可以獨立擴展。您能夠僅部署知足每一個服務的容量和可用性約束的實例數目。此外,您可使用與服務資源要求最匹配的硬件。例如,您能夠在 EC2 Compute Optimized 實例上部署一個 CPU 密集型圖像處理服務,而且在 EC2 Memory-optimized 實例上部署一個內存數據庫服務。
微服務架構模式也存在着缺點。其中一個缺點就是名稱自己。微服務這個術語的重點過多偏向於服務的規模。事實上,有些開發者主張構建極細粒度的 10 至 100 LOC(代碼行) 服務,雖然這對於小型服務可能比較好,但重要的是要記住,小型服務只是一種手段,而不是主要目標。微服務的目標在於充分分解應用程序以方便應用敏捷開發和部署。
微服務另外一個主要缺點是因爲微服務是一個分佈式系統,其使得總體變得複雜。開發者須要選擇和實現基於消息或者 RPC 的進程間通訊機制。此外,因爲目標請求可能很慢或者不可用,他們必需要編寫代碼來處理局部故障。雖然這些並非很複雜、高深,但模塊間經過語言級方法/過程調用相互調用,這比單體應用要複雜得多。
微服務的另外一個挑戰是分區數據庫架構。更新多個業務實體的業務事務是至關廣泛的。這些事務在單體應用中的實現顯得微不足道,由於單體只存在一個單獨的數據庫。在基於微服務的應用程序中,您須要更新不一樣服務所用的數據庫。一般不會選擇分佈式事務,不只僅是由於 CAP 定理。他們根本不支持現在高度可擴展的 NoSQL 數據庫和消息代理。您最後不得不使用基於最終一致性的方法,這對於開發人員來講更具挑戰性。
測試微服務應用程序也很複雜。例如,使用現代框架如 Spring Boot,只須要編寫一個測試類來啓動一個單體 web 應用程序並測試其 REST API。相比之下,一個相似的測試類對於微服務來講須要啓動該服務及其所依賴的全部服務,或者至少爲這些服務配置存根。再次聲明,雖然這不是一件高深的事情,但不要低估了這樣作的複雜性。
微服務架構模式的另外一個主要挑戰是實現了跨越多服務變動。例如,咱們假設您正在實現一個變動服務 A、服務 B 和 服務 C 的需求,其中 A 依賴於 B,且 B 依賴於 C。在單體應用程序中,您能夠簡單地修改相應的模塊、整合變動並一次性部署他們。相反,在微服務中您須要仔細規劃和協調出現的變動至每一個服務。例如,您須要更新服務 C,而後更新服務 B,最後更新服務 A。幸運的是,大多數變動只會影響一個服務,須要協調的多服務變動相對較少。
部署基於微服務的應用程序也是至關複雜的。一個單體應用能夠很容易地部署到基於傳統負載均衡器的一組相同服務器上。每一個應用程序實例都配置有基礎設施服務的位置(主機和端口),好比數據庫和消息代理。相比之下,微服務應用程序一般由大量的服務組成。例如,據 Adrian Cockcroft 瞭解到,Hailo 擁有 160 個不一樣的服務,Netflix 擁有的服務超過 600 個。
每一個服務都有多個運行時實例。還有更多的移動部件須要配置、部署、擴展和監控。此外,您還須要實現服務發現機制,使得服務可以發現須要與之通訊的任何其餘服務的位置(主機和端口)。比較傳統麻煩的基於票據(ticket-based)和手動的操做方式沒法擴展到如此複雜程度。所以,要成功部署微服務應用程序,須要求開發人員能高度控制部署方式和高度自動化。
一種自動化方式是使用現成的平臺即服務(PaaS),如 Cloud Foundry。PaaS 爲開發人員提供了一種簡單的方式來部署和管理他們的微服務。它讓開發人員避開了諸如採購和配置 IT 資源等煩惱。同時,配置 PaaS 的系統人員和網絡專業人員能夠確保達到最佳實踐以落實公司策略。
自動化微服務部署的另外一個方式是開發本身的 PaaS。一個廣泛的起點是使用集羣方案,如 Kubernetes,與 Docker 等容器技術相結合。
構建複雜的微服務應用程序本質上是困難的。單體架構模式只適用於簡單、輕量級的應用程序,若是您使用它來構建複雜應用,您最終會陷入痛苦的境地。微服務架構模式是複雜、持續發展應用的一個更好的選擇。儘管它存在着缺點和實現挑戰。
2000 年 7 月,加州大學伯克利分校的 Eric Brewer 教授在 ACM PODC 會議上提出 CAP 猜測。2年後,麻省理工學院的 Seth Gilbert 和 Nancy Lynch 從理論上證實了 CAP。以後,CAP 理論正式成爲分佈式計算領域的公認定理。
CAP 理論爲:一個分佈式系統最多隻能同時知足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。
經過 CAP 理論,咱們知道沒法同時知足一致性、可用性和分區容錯性這三個特性,那要捨棄哪一個呢?
對於多數大型互聯網應用的場景,主機衆多、部署分散,並且如今的集羣規模愈來愈大,因此節點故障、網絡故障是常態,並且要保證服務可用性達到 N 個 9,即保證 P 和 A,捨棄C(退而求其次保證最終一致性)。雖然某些地方會影響客戶體驗,但沒達到形成用戶流程的嚴重程度。
對於涉及到錢財這樣不能有一絲讓步的場景,C 必須保證。網絡發生故障寧肯中止服務,這是保證 CA,捨棄 P。貌似這幾年國內銀行業發生了不下 10 起事故,但影響面不大,報道也很少,廣大羣衆知道的少。還有一種是保證 CP,捨棄 A。例如網絡故障是隻讀不寫。
孰優孰略,沒有定論,只能根據場景定奪,適合的纔是最好的。
eBay 的架構師 Dan Pritchett 源於對大規模分佈式系統的實踐總結,在 ACM 上發表文章提出 BASE 理論,BASE 理論是對 CAP 理論的延伸,核心思想是即便沒法作到強一致性(Strong Consistency,CAP 的一致性就是強一致性),但應用能夠採用適合的方式達到最終一致性(Eventual Consitency)。
ACID 是傳統數據庫經常使用的設計理念,追求強一致性模型。BASE 支持的是大型分佈式系統,提出經過犧牲強一致性得到高可用性。
ACID 和 BASE 表明了兩種截然相反的設計哲學,在分佈式系統設計的場景中,系統組件對一致性要求是不一樣的,所以 ACID 和 BASE 又會結合使用。