微服務能夠拆分爲"微"和"服務"二字。"微"即小的意思,那到底多小纔算"微"呢?可能不一樣的團隊有不一樣的答案。從參與微服務的人數來說,單個微服務從架構設計、代碼開發、測試、運維人數加起來是8~10人才算"微"。那麼何爲"服務"呢?按照"微服務"概念提出者Martin Fowler給出的定義:"服務"是一個獨立運行的單元組建,每一個單元組件運行在獨立的進程中,組件與組件之間一般使用HTTP這種輕量級的通訊機制進行通訊。微服務具備如下特色:前端
微服務具備以上這些特色,那麼微服務須要具有一些什麼樣的功能呢?微服務的功能主要體如今如下幾個方面:程序員
1.服務的註冊與發現
微服務系統由不少個單一職責的服務單元組成,例如Netflix公司的系統是由600多個微服務構成的,而每個微服務又有衆多實例。因爲該系統的服務粒度較小,服務數量衆多,服務之間的相互依賴呈網狀,因此該系統須要服務註冊中心來統一管理微服務實例,方便查看每個微服務實例的健康狀態。
服務註冊是指向服務註冊中心註冊一個服務實例,服務提供者將本身的服務信息(如服務名、IP地址等)告知服務註冊中心。服務發現是指當服務消費者須要消費另一個服務時,服務註冊中心可以告知服務消費者它所要消費服務的實例信息(如服務名、IP地址等)。一般狀況下,一個服務既是服務提供者,也是服務消費者。服務消費者通常使用HTTP協議或者消息組件這種輕量級的通訊機制來進行服務消費。服務的註冊與發現以下如所示:
服務註冊中心會提供服務的健康檢查方案,檢查被註冊的服務是否可用。一般一個服務實例註冊後,會定時向服務註冊中心提供"心跳",以代表本身還處於可用的狀態。當一個服務實例中止向服務註冊中心提供心跳一段時間後,服務註冊中心會認爲該服務實例不可用,會將該服務實例從服務註冊列表中剔除。若是這個被剔除掉的服務實例過一段時間後繼續向註冊中心提供心跳,那麼服務註冊中心會將該服務實例從新假如服務註冊中心的列表中。另外,微服務的服務註冊組件都會提供服務的健康情況查看的UI界面,開發人員或運維人員只須要登錄相關的界面就能夠知道服務的健康狀態。spring
2.服務的負載均衡
在微服務結構中,服務之間的相互調用通常是經過HTTP通訊協議來實現的。網絡每每具備不可靠性,爲了保證服務的高可用(High Availability),服務單元每每是集羣化部署。例如將服務提供者進行集羣化不舒服,那麼服務消費者該調用哪一個服務提供者的實例呢?這就涉及到了服務的負載均衡。
服務的負載均衡通常最流行的作法以下如所示,全部的服務都向服務註冊中心註冊,服務註冊中心持有每一個服務的
應用名和IP地址等信息,同時每一個服務也會獲取全部服務註冊列表信息。服務消費者集成負載均衡組件,該組件會向服務消費者獲取服務註冊列表,並每隔一段時間從新刷新獲取該列表。當服務消費者消費服務時,負載均衡組件獲取服務提供者全部實例的註冊信息,並經過必定的負載均衡策略(開發者能夠配置),選擇一個服務提供者的實例,向該實例進行服務消費,這樣就實現了負載均衡。
服務註冊中心不但須要定時接收每一個服務的心跳(用來檢查服務是否可用),並且每一個服務會按期獲取服務註冊列表的信息,當服務實例數量不少時,服務註冊中心承擔了很是大的負載。因爲服務註冊中心在微服務系統中起到了相當重要的做用,因此必須實現高可用。通常的作法是將服務註冊中心集羣化,每一個服務註冊中的數據實時同步,以下圖所示:
數據庫
3.服務的容錯
微服務落地到實際項目中,服務的數量每每很是多,服務之間的相互依賴性也是錯綜複雜的,一個網絡請求一般須要調用多個服務才能完成。若是一個服務不可用,例如網絡延遲或故障,會影響到依賴於這個不可用的服務的其餘服務。以下圖所示:
一個微服務系統有不少服務,當服務F因某些緣由致使了服務的不可用,來自於用戶的網絡請求須要調用服務F。因爲服務F無響應,用戶的請求都處於阻塞狀態,在高併發的場景下,短期內會致使服務器的線程資源消耗殆盡。另外,依賴於服務F的其餘服務,例如圖中的服務E、服務G、服務J,也會等待服務F的響應,處於阻塞狀態,致使這寫服務的線程資源消耗殆盡,進而致使它們的不可用,以及依賴於它們的服務的不可用,最後致使整個系統處於癱瘓的狀態,也就是"雪崩效應"。
爲了解決分佈式系統的雪崩效應,分佈式系統引進了熔斷器機制。熔斷器(Circuit Breaker)一詞來源於物理學中的電路知識,它的做用是當電路中出現故障時迅速切斷電源,起到保護電路的做用,熔斷器機制以下圖所示:
當一個服務的處理用戶請求的失敗次數在必定時間內小於設定的閥值時,熔斷器處於關閉狀態,服務正常;當服務處理用戶請求的失敗次數大於設定的閥值時,說明服務出現了故障,打開熔斷器,這時全部的請求會執行快速失敗,不執行業務邏輯。當處於打開狀態的熔斷器時,一段時間後會處於半打開狀態,並執行必定數量的請求,剩餘的請求會執行快速失敗,若執行的請求失敗了,則繼續打開熔斷器;若成功了,則將熔斷器關閉。
這種機制有着很是重要的意義,它不只可以防止系統的"雪崩"效應,還具備如下做用:後端
Netflix的Hystrix熔斷器開源組件功能很是強大,不只有熔斷器的功能,還有熔斷器的狀態監測,並提供有好的UI,開發人員或者運維人員經過UI界面可以直觀地看到熔斷器的狀態和各類性能指標。緩存
4.服務網關
微服務系統經過將資源以API接口的形式暴露給外界來提供服務。在微服務系統中,API接口資源一般是由服務網關(也稱API網關)統一暴露,內部服務不直接對外提供API資源的暴露。這樣作的好處是將內部服務隱藏起來,外界還覺得是一個服務在提供服務,在必定程度上保護了微服務系統的安全。API網關一般有請求轉發的做用,另外它可能須要負責必定的安全驗證,網關層以集羣的形式存在。在服務網關層以前,可能須要加上負載均衡層,一般爲Nginx雙機熱備,經過必定的路由策略,將請求轉發到網關層。到達網關層後,通過一系列的用戶身份驗證、權限判斷,最終轉發到具體的服務。具體的服務通過一系列的邏輯運算和數據操做,最終將結果返回給用戶,此時的架構以下圖所示:
網關層具備很重要的意義,具體體如今如下方面:安全
固然,網關實現這些功能,須要作高可用,不然網關極可能成爲架構中的瓶頸。最經常使用的網關組件有Zuul、Nginx等。服務器
5.服務配置的統一管理
在實際開發過程當中,每一個服務都有大量的配置文件,例如數據庫的配置、日誌輸出級別的配置等,而每每這些配置在不一樣的環境中也是不同的。隨着服務數量的增長,配置文件的管理也是一件很是複雜的事。
在微服務架構中,須要有統一管理配置文件的組件,例如Spring Cloud的Spring Cloud Config組件、阿里的Diamond、百度的Disconf、攜程的Apollo等。這些配置組件所實現的功能大致相同,可是又有些差異,如下以Spring Cloud Config爲例來闡述服務配置的統一管理。大體過程以下如圖所示:
網絡
對於集羣化的服務,能夠經過使用消息總線來刷新多個服務實例。若是服務數量較多,對配置中心須要考慮集羣化部署,從而使配置中心高可用,作分佈式集羣。多線程
6.服務鏈路追蹤
微服務系統是一個分佈式架構的系統,微服務系統按業務劃分服務單元,一個微服務系統每每有不少各服務單元。因爲服務單元數量不少且業務複雜,服務與服務之間的調用有可能很複雜,一旦出現了異常和錯誤,就會很難去定位。因此在微服務架構中,必須實現分佈式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而使每一個請求鏈路清晰可見,出了問題很快就能定位。例以下圖:
在微服務系統中,一個來自用戶的請求先到達前端A(如前端界面),而後經過遠程調用,到達系統的中間件B、C(如負載均衡、網關等),最後到達後端服務D、E。後端通過一系列的業務邏輯計算,最後將數據返回給用戶。對於這樣一個請求,經歷了這麼多服務,怎麼樣將其請求過程的參數記錄下來呢?這就須要用到服務鏈路追蹤。
Google開源了鏈路追蹤組件Dapper,並在2010年發表了論文《Dapper, a Large-Scale Distributed Systems Tracing In仕astructure》,這篇論文是業內實現鏈路追蹤的標杆和理論基礎,具備很是高的參考價值。
目前,常見的鏈路追蹤組件有Google的Dapper、Twitter的Zipkin,以及阿里的Eagleeye(鷹眼)等,都是很是優秀的鏈路追蹤開源組件。
1.Spring Cloud簡介
Spring Cloud是基於Spring Boot的。Spring Boot是由Pivotal團隊提供的全新Web框架,它主要的特色就是簡化了開發和部署的過程,簡化了Spring複雜的配置和依賴管理,經過起步依賴和內置Servlet容器可以使開發者迅速搭建起一個Web工程。因此Spring Cloud在開發部署上繼承了Spring Boot的一些優勢,提升其在開發和部署上的效率。
Spring Cloud的首要目標就是經過提供一系列開發組件和框架,幫助開發者迅速搭建一個分佈式的微服務系統。Spring Cloud是經過包裝其餘技術框架來實現的,例如包裝開源的Netflix OSS組件,來實現了一套經過基於註解、Java配置和基於模板開發的微服務框架。Spring Cloud框架來自於Spring Resouces社區,有Pivotal和Netflix兩大公司和一些其它的開發者提供技術上的更新迭代。Spring Cloud提供了開發分佈式微服務系統的一些經常使用組建,例如服務註冊和發現、配置中心、熔斷器、智能路由、微代理、控制總線、全局鎖、分佈式會話等。
2.經常使用組件
(1)服務註冊和發現組件 Eureka
利用Eureka組件能夠很輕鬆地實現服務的註冊和發現功能。Eureka組件提供了服務的健康監測,以及界面友好的UI。經過Eureka組件提供的UI,Eureka組建可讓開發人員隨時瞭解服務單元的運行狀況。另外Spring Cloud也支持Consul和Zookeeper,用於註冊和服務發現。
(2)熔斷組件 Hystrix
Hystrix是一個熔斷組件,它除了有一些基本的熔斷器功能外,還可以實現服務降級、服務限流的功能。另外Hystrix提供了熔斷器的健康監測,以及熔斷器健康數據的API接口。Hystrix Dashboard組件提供了單個服務熔斷器的健康狀態數據的界面展現功能,Hystrix Turbine組件提供了多個服務的熔斷器的健康狀態數據的界面展現功能。
(3)負載均衡組件 Ribbon
Ribbon是一個負載均衡組件,它一般和Eureka、Zuul、RestTemplate、Feign配合使用。Ribbon和Zuul配合,很容易作到負載均衡,將請求根據負載均衡策略分配到不一樣的服務實例中。Ribbon和RestTemplate、Feign配合,在消費服務時可以作到負載均衡。
(4)路由網關 Zuul
路由網關Zuul有隻能路由和過濾的功能。內部服務的API接口經過Zuul網關統一對外暴露,內部服務的API接口不直接暴露,防止了內部服務敏感信息對外暴露。在默認狀況下,Zuul和Ribbon相結合,可以作到負載均衡、智能路由。Zuul的過濾功能是經過攔截請求來實現的,能夠對一些用戶的角色和權限進行判斷,起到安全驗證的做用,同時也能夠用於輸出實時的請求日誌。
上述4各組件都來自於Netflix公司,統一稱爲Spring Cloud Netflix。
(5)Spring Cloud Config
Spring Cloud Config組件提供了配置文件統一管理的功能。Spring Cloud Config包括Server端和Client端,Server端讀取本地倉庫或遠程倉庫的配置文件,全部的Client向Server讀取配置信息,從而達到配置文件統一管理的目的。一般狀況下,Spring Cloud Config和Spring Cloud Bus相互配置刷新指定Client或全部Client的配置文件。
(6)Spring Cloud Security
Spring Cloud Security是對Spring Security組件的封裝,Spring Cloud Security向服務單元提供了用戶驗證和權限認證。通常來講,單獨再微服務系統中使用Spring Cloud Security是不多見的,通常它會配合Spring Security OAuth2組件一塊兒使用,經過搭建受權服務,驗證Token或者JWT這種形式對整個微服務系統進行安全驗證。
(7)Spring Cloud Sleuth
Spring Cloud Sleuth是一個分佈式鏈路追蹤組件,它封裝了Dapper、Zipkin和Kibana等組件,經過它能夠知道服務之間的相互依賴關係,並實時觀察鏈路的調用狀況。
(8)Spring Cloud Stream
Spring Cloud Stream是Spring Cloud框架的數據流操做包,能夠封裝RabbitMQ、ActiveMQ、Kafka、Redis等消息組件,利用Spring Cloud Stream能夠實現消息的接收和發送。
上述列舉了一些經常使用的Spring Cloud組件。一個簡單的由Spring Cloud構建的微服務系統,一般由服務註冊中心Eureka、網關Zuul、配置中心Config和受權服務Auth構成,其架構以下圖所示:
Dubbo是阿里巴巴開源的一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。Dubbo普遍用於阿里巴巴的各大站點,有不少互聯網公司也在使用這個框架,它包含的核心內容以下:
Dubbo框架圖以下所示:
Dubbo框架的流程以下:
Dubbo是一個很是優秀的服務治理框架,在國內互聯網公司應用普遍,它具備如下特性:
首先,從微服務關注點來比較Spring Cloud和Dubbo兩大服務框架,以下表所示:
Spring Cloud擁有不少的項目模塊,包含了微服務系統的方方面面。Dubbo是一個很是優秀的服務治理和服務調用框架,但缺乏不少功能模塊,例如網關、鏈路追蹤等。在項目模塊上,Spring Cloud佔據更大的優點。
Spring Cloud的更新速度很是快,從GitHub的代碼倉庫來看,Spring Cloud幾乎天天都有更新。
從學習成原本看,Dubbo版本趨於穩定,文檔完善,能夠即學即用,沒有太大難度。Spring Cloud基於Spring Boot開發,須要開發者先學會Spring Boot。另外Spring Cloud版本迭代塊,須要快速跟進學習。
從開發風格上來說,Dubbo更傾向於Spring Xml的配置方式,Dubbo官方也推薦這種方式。Spring Cloud基於Spring Boot,Spring Boot採用的是基於註解和JavaBean配置方式的敏捷開發。從開發速度上講,Spring Cloud具備更高的開發和部署速度。
最後,Spring Cloud的通訊方式大多數時基於HTTP Restful風格的,服務與服務之間徹底無關、無耦合。因爲採用的是HTTP Restful,所以服務無關乎語言和平臺,只須要體統相應API接口,就能夠調用。Dubbo的通訊方式基於遠程調用,對接口、平臺和語言有強依賴性。若是須要實現跨平臺調用服務,須要寫額外的中間件,這也是Dubbo
存在的緣由。
Kubernetes是一個容器集羣管理系統,爲容器化的應用程序提供部署運行、維護、擴展、資源調度、服務發現等功能。Kubernetes時Google運行Borg大規模系統達15年之久的一個經驗總結。Kubernetes結合了社區的最佳創意和實踐,旨在幫助開發人員將容器打包、動態編排,同時幫助各大公司向微服務方向進行技術演進。其具備如下特色:
Kubernetes開源免費,時Google在過去15年時間裏部署、管理微服務的經驗結晶,因此目前Kubernetes在技術社區也十分火熱,下面看看它提供的功能:
從Kubernetes提供的功能來看,Kubernetes徹底能夠成爲構建和部署微服務的一個工具,它是從服務編排上實現的,而不是從代碼實現的。目前國外有不少知名的公司在使用Kubernetes,如Google、eBay、Pearson等。因爲它的開源免費,Microsoft、VMWare、Red Hat、CoreOS等公司紛紛加入並貢獻代碼。Kubernetes技術吸引了一大批公司和技術愛好者,它已經成爲容器管理的領導者。
Spring Could是一個構建微服務的框架,兒Kubernetes是經過對運行的容器的編排來實現構建微服務。二者從構建微服務的角度和實現方式有很大的不一樣,但它們提供了構建微服務所需的所有功能。從提供的微服務所需的功能上看,二者不分上下,以下表所示:
Spring Cloud經過衆多的類庫來實現微服務系統所需的各個組件,同時不斷集成優秀的組件,因此Spring Cloud組件是很是完善的。Spring Cloud基於Spring Boot框架,有快速開發、快速部署的優勢。對於Java開發者來講,學習Spring Cloud的成本不高。
Kubernetes在編排上解決微服務的各個功能,例如服務發現、配置管理、負載均衡、容錯等。Kubernetes不限於Java平臺,也不侷限於語言,開發者能夠自由選擇開發語言進行項目開發。
與Kubernetes相比,Spring Cloud具備如下優勢:
與Kubernetes比較,Spring Cloud具備如下缺點:
下面介紹Kubernetes的優勢和缺點,優勢以下:
Kuberbetes的缺點以下:
Spring Cloud 嘗試從Java 類庫來實現微服務的全部功能,而Kubernetes 嘗試從容器編排上實現全部的微服務功能,二者的實現角度和方式不同。我的以爲,二者最終的實現功能和效果上不分勝負,但從實現的方式上來說, Kubernetes 略勝一籌。Kubernetes 面向DevOps 人員,學習成本高。Spring Cloud 有不少的類庫,以Spring 爲基礎,繼承了Spring Boot 快速開發的優勢,爲Java 程序員開發微服務提供了很好的體驗,學習成本也較低。因此兩者比較,各有優點。沒有最好的框架,也沒有最好的工具,關鍵是要適合業務需求和知足業務場呆。