深入理解SpringCloud與微服務構建
旭日Follow_24 的CSDN 博客 ,全文地址請點擊:
https://blog.csdn.net/xuri24/article/details/81742534
目錄
一、SpringCloud微服務技術簡介
1.1 微服務的功能主要體現在以下兒個方面。
1.2 微服務具有以下的特點。
二、開發框架SpringBoot
三、服務註冊和發現Ereka
3.1 什麽是Eureka
3.2 Ereka優勢
( l ) Registe 「一一服務註冊
(2) Renew一一服務續約
(3) Fetch Registries一一獲取服務註冊列表信息
( 4) Cancel -一服務下線
( 5 ) Eviction一一服務剔除
四、負載均衡
五、申明式調用
5.1 申明式Feign的簡介
5.2 Feign簡單構建
六、熔斷器
6.1 什麽是Hystrix
6.2 Hystrix的作用
6.3 Hystrix的場景
6.4 Hystrix設計原則
6.5 Hystrix 的工作機制
6.6 Hystrix Dashboard 是監控Hystrix 的熔斷器狀態
七、路由網關
7.1 Zuul的作用
7.2 Zuul的工作原理
7.3 在Zuul 上配置熔斷器
7.4 在Zuul 中使用過濾器
5.Zuul 的常見使用方式
八、配置中心
8.1 分布式配置中心Spring Cloud Config
口Config Server 從本地讀取配置文件。
口Config Server 從遠程Git 倉庫讀取配置文件。
口搭建高可用Co nfig Server 集群。
口使用Spring Cloud Bus 刷新配置。
九、服務鏈路追蹤
口Config Server 從本地讀取配置文件。
口Config Server 從遠程Git 倉庫讀取配置文件。
口搭建高可用Config Server 集群。
口使用Spring Cloud Bus 刷新配置。
十、微服務監控
十一、SpringSecurity
一、SpringCloud微服務技術簡介
Spring Cloud 作為Java 語言的微服務框架,它依賴於Spring Boot,有快速開發、持續交付和
容易部署等特點。Spring Cloud 的組件非常多,涉及微服務的方方面面,井在開源社區Spring 和
Netflix 、Pivotal 兩大公司的推動下越來越完善。
1.1 微服務的功能主要體現在以下兒個方面。
口服務的註冊和發現。
口服務的負載均衡。
口服務的容錯。
口服務網關。
口服務配置的統一管理。
口鏈路追蹤。
口實時日誌。
1.2 微服務具有以下的特點。
口按照業務來劃分服務,單個服務代碼量小,業務單一,易於維護。
口每個微服務都有自己獨立的基礎組件,例如數據庫、緩存等,且運行在獨立的進程中。
口微服務之間的通信是通過HTTP 協議或者消息組件,且具有容錯能力。
口微服務有一套服務治理的解決方案,服務之間不相合,可以隨時加入和剔除服務。
口單個微服務能夠集群化部署,並且有負載均衡的能力。
口整個微服務系統應該有一個完整的安全機制,包括用戶驗證、權限驗證、資源保護等。
口整個微服務系統有鏈路追蹤的能力。
口有一套完整的實時日誌系統。
二、開發框架SpringBoot
三、服務註冊和發現Ereka
3.1 什麽是Eureka
和Consul 、Zookeeper 類似, Eureka 是一個用於服務註冊和發現的組件,最開始主要應用
於亞馬遜公司旗下的雲計算服務平臺AWS o Eureka 分為Eureka Server 和Eureka Client, Eureka
Server 為Eureka 服務註冊中心, Eureka Client 為Eureka 客戶端。
3.2 Ereka優勢
Eureka 和其他組件,比如負載均衡組件Ribbon 、熔斷器組件Hys往以、熔斷器監控組
件Hystrix Dashboard 組件、熔斷器聚合監控Turbine 組件,以及網關Zuul 組件相互配合, 能夠
很容易實現服務註冊、負載均衡、熔斷和智能路由等功能。這些組件都是由Netflix 公司開源的,
一起被稱為Netflix OSS 組件。Netflix OSS 組件由Spring Cloud 整合為Spring Cloud Netflix 組件,
Eureka 的基本架構如|到2-1 所示,其中主要包括以下3 種角色。
口Register Service :服務註冊中心,它是一個Eureka Server ,提供服務註冊和發現的功能。
口Provider Service :服務提供者,它是一個Eureka Client ,提供服務。
口Consumer Service :服務消費者,它是一個Eureka Cient ,消費服務。
服務消費的基本過程如下:首先前要一個服務註冊中心Eureka Server ,服務提供者Eureka
Client 向服務註冊中心Eureka Server 註冊,將自己的信息(比如服務名和服務的IP 地址等)
通過阻ST A 凹的形式提交給服務註冊中心Eureka Server 。同樣,服務消費者Eureka Client 也
向服務註冊1j1,L,, Eureka Server 註冊,同時服務消費者獲取一份服務註冊列表的信息, 該列表
包含了所有向脫務註冊中心Eureka Server 註冊的服務信息。獲取服務註冊列表信息之後,服
務消費者就知道服務提供者的IP 地址,可以通過Htφ 遠程調度來消費服務提供者的服務。
( l ) Registe 「一一服務註冊
當E ureka Client 向Eureka Server 註冊時, Eureka Client 提供自身的元數據,比如IP 地址、
端口、運行狀況H1 標的Uri 、主頁地址等信息。
(2) Renew一一服務續約
Eureka C li ent 在默認的情況下會每隔30 秒發送一次心跳來進行服務續約。通過服務續約
來告知E ureka Server 該Eureka Client 仍然可用,沒有出現故障。正常情況下,如果E ureka Server
在90 秒內沒有收到Eureka Client 的心跳, Eureka Server 會將Eureka Client 實例從註冊列表中
刪除。註意:’盯網建議不要更t& 服務續約的間隔時間。
(3) Fetch Registries一一獲取服務註冊列表信息
Eureka Client 從Eureka Server 獲取服務註冊表信息,井將其緩存在本地。Eureka Client 會
使用服務註冊列表信息查找其他服務的信息,從而進行遠程調用。該註冊列表信息定時(每
30 秒) 更新一次,每次返回註冊列表信息可能與Eureka Client 的緩存信息不同, Eureka Client
會自己處理這些信息。如呆由於某種原因導致註冊列表信息不能及時匹配, Eureka Client 會重
新獲取整個註冊表信息。Eureka Server 緩存了所有的服務註冊列表信息,並將整個註冊列表以
及每個應用程序的信息進行了壓縮,壓縮內容和沒有壓縮的內容完全相同。Eureka Client 和
Eureka Server 可以使用JSON 和XML 數據格式進行通信。在默認的情況下, Eureka Client 使
用JSON 格式的方式來獲取服務註冊列表的信息。
( 4) Cancel -一服務下線
Eureka Client 在程序關閉時可以向Eureka Server 發送下線請求。發送請求後,該客戶端的
實例信息將從E ureka Server 的服務註冊列表中刪除。該下線請求不會自動完成,需要在程序
關閉時調用以下代碼:
DiscoveryManager . getinstance() .shutdownComponent();
( 5 ) Eviction一一服務剔除
在默認情況下,當Eureka Client 連續90 秒沒有向Eureka Server 發送服務續約(即心跳〉
時, Eureka Server 會將該服務實例從服務註冊列表刪除,即服務剔除。
四、負載均衡
五、申明式調用
5.1 申明式Feign的簡介
@Feign Client 註解用於創建聲明式API 接口,該接口是阻STful 風格的。Feign 被設計成
插拔式的,可以註入其他組件和Feign 一起使用。最典型的是如果Ribbon 可用, Feign 會和
Ribbon 相結合進行負載均衡。
在代碼中, value()和name()一樣,是被調用的服務的Serviceld 。url ()直接填寫硬編碼的
Uri 地址。decode404()即404 是被解碼,還是拋異常。configuration ()指明FeignClient 的配置類,
默認的配置類為FeignClientsConfiguration 類, 在缺省的情況下, 這個類註入了默認的Decoder 、
Encoder 和Contract 等配置的Bean 。fallback()為配置熔斷器的處理類。
配置如下:
spring :
application :
name : eureka-feign-client
server:
port : 8765
eureka :
client :
serv 工ceUrl :
defaultZone: http://localhost:8761/eureka/
在程序的啟動類EurekaFeignClientApplication 加上註解@E nableEurekaCJ ient 開啟Eureka
Client 的功能,通過註解@EnableFeignClients 開啟Feign Client 的功能。代碼如下:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class EurekaFeignClientApplication {
public static void main (String [] args) {
SpririgApplication . run(EurekaFeignClientApplication.class , args) ;
5.2 Feign簡單構建
通過以上3 個步驟,該程序就具備了Feign 的功能,現在來實現一個簡單的Feign Client o
新建一個EurekaClientFeign 的接口,在接口上加@FeignClient 註解來聲明一個Fe ign Client,
其中value 為遠程調用其他服務的服務名, FeignConfig.class 為Feign Client 的配置類。在
EurekaClientFeign 接口內部有一個sayHiFromClientEureka()方法,該方法通過Feign 來調用
eureka-client 服務的“ 曠的API 接口
六、熔斷器
6.1 什麽是Hystrix
在分布式系統中,服務與服務之間的依賴錯綜復雜, 一種不可避免的情況就是某些服務會
出現故障,導致依賴於它們的其他服務出現遠程調度的線程阻塞。Hystrix 是Netflix 公司開
源的一個項目,它提供了熔斷器功能,能夠阻止分布式系統中出現聯動故障。Hystrix 是通過
隔離服務的訪問點阻止聯動故障的,並提供了故障的解決方案,從而提高了整個分布式系統
的彈性。
6.2 Hystrix的作用
在復雜的分布式系統中,可能有幾十個服務相互依賴,這些服務由於某些原因,例如機房
的不可靠性、網絡服務商的不可靠性等,導致某個服務不可用。如果系統不隔離該不可用的服務,可能會導致整個系統不可用。
例如,對於依賴30 個服務的應用程序,每個服務的正常運行時間為99.99% ,對於單個服務來說, 99.99% 的可用是非常完美的。有99.9930 = 99.7% 的可正常運行時間和0.3% 的不可用時間,那麽10 億次請求中有3000000次失敗,實際的情況可能比這更糟糕。如果不設計整個系統的韌性,即使所有依賴關系表現良好,單個服務只有0.01% 的不可用,由於整個系統的服務相互依賴,最終對整個系統的影響是非常大的。在微服務系統中, 一個用戶請求可能需要調用幾個服務才能完成。如圖8-1 所示,在所有的服務都處於可用狀態時, 一個用戶請求需要調用A 、H 、I 和P 服務。
6.3 Hystrix的場景
當某一個服務,例如服務I,出現網絡延遲或者故障時,即使服務A 、H 和P 可用,由於
服務I 的不可用,整個用戶請求會處於阻塞狀態,並等待服務I 的響應,如圖8-2 所示。
在高並發的情況下,單個服務的延遲會導致整個請求都處於延遲狀態,可能在幾秒鐘就使
整個服務處於線程負載飽和的狀態。
某個服務的單個點的請求故障會導致用戶的請求處於阻塞狀態,最終的結果就是整個服務
的線程資源消耗殆盡。由於服務的依賴性,會導致依賴於該故障服務的其他服務也處於線程阻
塞狀態,最終導致這些服務的線程資源消耗殆盡, 直到不可用,從而導致整個問服務系統都不
可用,即雪崩效應。
為了防止雪崩效應,因而產生了熔斷器模型。Hystrix 是在業界表現非常好的一個熔斷器
模型實現的開源組件,它是Spring Cloud 組件不可缺少的一部分。
6.4 Hystrix設計原則
Hystrix 的設計原則如下。
口防止單個服務的故障耗盡整個服務的Servlet 容器(例如Tomcat )的線程資源。
口快速失敗機制,如果某個服務出現了故障,則調用該服務的請求快速失敗,而不是線
程等待。
口提供回退( fallback )方案,在請求發生故障時,提供設定好的回退方案。
口使用熔斷機制,防止故障擴散到其他服務。
口提供熔斷器的監控組件Hystrix Dashboard,可以實時監控熔斷器的狀態。
6.5 Hystrix 的工作機制
當服務的某個API 接口的失敗次數
在一定時間內小於設定的閥值時,熔斷器處於關閉狀態,該API 接口正常提供服務。當該
API 接口處理請求的失敗次數大於設定的閥值時, Hystrix 判定該API 接口出現了故障,打開
熔斷器,這時請求該API 接口會執行快速失敗的邏輯(即fallback 回退的邏輯),不執行業
務邏輯,請求的線程不會處於阻塞狀態。處於打開狀態的熔斷器, 一段時間後會處於半打開
狀態,並將一定數量的請求執行正常邏輯。剩余的請求會執行快速失敗,若執行正常邏輯的
請求失敗了,則熔斷器繼續打開: 若成功了,則將熔斷器關閉。這樣熔斷器就具有了自我修
復的能力。
6.6 Hystrix Dashboard 是監控Hystrix 的熔斷器狀態
在微服務架構中,為了保證服務實例的可用性,防止服務實例出現故障導致線程阻塞,而
出現了熔斷器模型。烙斷器的狀況反映了一個程序的可用性和健壯性,它是一個重要指標。
Hystrix Dashboard 是監控Hystrix 的熔斷器狀況的一個組件,提供了數據監控和l 友好的圖形化
展示界面。本節在上一節的基礎上,以案例的形式講述如何使用Hystrix Dashboard 監控熔斷
器的狀態。
七、路由網關
智能路由網關組件Zuul:Zuul 作為微服務系統的網關組件,用於構建邊界服務( Edge
Service ),致力於動態路由、過濾、監控、彈性伸縮和安全。
7.1 Zuul的作用
Zuul 作為路由網關組件,在微服務架構中有著非常重要的作用,主要體現在以下6 個方面。
D Zuul 、Ribbon 以及Eureka 相結合,可以實現智能路由和負載均衡的功能, Zuul 能夠
將請求流量按某種策略分發到集群狀態的多個服務實例。
口網關將所有服務的API 接口統一聚合,並統一對外暴露。外界系統調用API 接口時,
都是由網關對外暴露的API 接口,外界系統不需要知道微服務系統中各服務相互調
用的復雜性。微服務系統也保護了其內部微服務單元的API 接口, 防止其被外界直
接調用,導致服務的敏感信息對外暴露。
口網關服務可以做用戶身份認證和權限認證,防止非法請求操作API 接口,對服務器
起到保護作用。
口網關可以實現監控功能,實時日誌輸出,對請求進行記錄。
口網關可以用來實現流量監控, 在高流量的情況下,對服務進行降級。
口API 接口從內部服務分離出來, 方便做測試。
7.2 Zuul的工作原理
Zuul 是通過Servlet 來實現的, Zuul 通過自定義的Zuu!Servlet (類似於Spring MVC 的
DispatcServlet〕來對請求進行控制。Zuul 的核心是一系列過濾器,可以在Http 請求的發起和
響應返回期間執行一系列的過濾器。Zuul 包括以下4 種過濾器。
口PRE 過濾器: 它是在請求路由到具體的服務之前執行的,這種類型的過濾器可以做
安全驗證,例如身份驗證、參數驗證等。
口ROUTING 過濾器: 它用於將請求路由到具體的微服務實例。在默認情況下,它使用
Http Client 進行網絡請求。
口POST 過濾器:它是在請求己被路由到微服務後執行的。一般情況下,用作收集統計
信息、指標,以及將響應傳輸到客戶端。
口ERROR 過濾器:它是在其他過濾器發生錯誤時執行的。
Zuul 采取了動態讀取、編譯和運行這些過濾器。過濾器之間不能直接相互通信,而是通
過RequestContext 對象來共享數據, 每個請求都會創建一個RequestContext 對象。Zuul 過濾器
具有以下關鍵特性。
口Type (類型) : Zuul 過濾器的類型,這個類型決定了過濾器在請求的哪個階段起作用,
例如Pre 、Post 階段等。
口Execution Order (執行順序) :規定了過濾器的執行順序, Order 的值越小,越先執行。
口Criteria (標準) : Filter 執行所需的條件。
口Action (行動〉: 如果符合執行條件,則執行Action (即邏輯代碼)。
Zuul 請求的生命周期如圖9-1 所示,該圖來自Zuul 的官方文檔。
當一個客戶端Request 請求進入Zuul 網關服務時,網關先進入“pre filter飛進行一系列
的驗證、操作或者判斷。然後交給“routing filter ”進行路由轉發,轉發到具體的服務實例進
行邏輯處理、返回數據。當具體的服務處理完後,最後由“post filter ,,進行處理, 該類型的處
理器處理完之後,將Response 信息返回給客戶端。
7.3 在Zuul 上配置熔斷器
Zuul 作為Netflix 組件,可以與Ribbon 、Eureka 和Hystrix 等組件相結合,實現負載均衡、
熔斷器的功能。在默認情況下, Zuul 和Ribbon 相結合, 實現了負載均衡的功能。下面來講解
如何在Zuul 上實現熔斷功能。
在Zuul 中實現熔斷功能需要實現ZuulFallbackProvider 的接口。實現該接口有兩個方法, 一個
是getRouteO方法,用於指定熔斷功能應用於哪些路由的服務; 另一個方法fallbackResponseO為進
入熔斷功能時執行的邏輯
7.4 在Zuul 中使用過濾器
在前面的章節講述了過濾器的作用和種類,下面來講解如何實現一個自定義的過濾器。
實現過濾器很簡單, 只需要繼承ZuulFilter ,井實現Zuu!Filter 中的抽象方法,包括filterType()
和filterOrder(),以及IZuulFilter 的shouldFilter()和0均ect run()的兩個方法。其中, filterType()
即過濾器的類型,在前文已經講解過了,它有4 種類型,分別是“ pre '’“ post ”“ routing ”和
“ error ” 。白lterOrder()是過濾順序,它為一個Int 類型的值,值越小,越早執行該過濾器。
shouldFilter()表示該過濾器是否過濾邏輯,如果為true ,則執行run()方法:如果為false ,則
不執行run ()方法。run ()方法寫具體的過濾的邏輯。
5.Zuul 的常見使用方式
Zuul 是采用了類似於Spring MVC 的DispatchServlet 來實現的,采用的是異步阻塞模型,
所以性能比Ngnix 差。由於Zuul 和其他Netflix 組件可以相互配合、無縫集成, Zuul 很容易
就能實現負載均衡、智能路由和熔斷器等功能。在大多數情況下, Zuul 都是以集群的形式存
在的。由於Z u川的橫向擴展能力非常好,所以當負載過高時,可以通過添加實例來解決性
能瓶頸。
一種常見的使用方式是對不同的渠道使用不同的Zuul 來進行路由,例如移動端共用一個
Zuul 網關實例, Web 端用另一個Zuul 網關實例,其他的客戶端用另外一個Zuul 實例進行路由。
這種不同的渠邊用不同Zuul 實例的架構如圖9-3 所示。
八、配置中心
8.1 分布式配置中心Spring Cloud Config
口Config Server 從本地讀取配置文件。
Config Server 可以從本地倉庫讀取配置文件,也可以從遠處Git 倉庫讀取。本地倉庫是指
將所有的配置文件統一寫在Config Server 工程目錄下。Config Sever 暴露HttpAPI 接口, Config
Client 通過調用Config Sever 的H即API 接口來讀取配置文件。
spring:
cloud :
config :
server :
native :
search-locations: classpath : /shared
profiles :
active : native
application :
name : config- server
server :
port : 8769
在工程的Resources 目錄下建一個shared 文件夾,用於存放本地配置文件。在shared 目錄
下,新建一個config-client-dev. ym l 文件,用作eureka-client 工程的dev (開發環境〉的配置文
件。在config-client-dev.yml 配置文件中,指定程序的端口號為8762 , 並定義一個變fil foo , 該
變量的值為foo version l。
口Config Server 從遠程Git 倉庫讀取配置文件。
Spring Cloud Config 支持從遠程Git 倉庫讀取配置文件,即Config Server 可以不從本地的
倉庫讀取,而是從遠程Git 倉庫讀取。這樣做的好處就是將配置統一管理,並且可以通過Spring
Cloud Bus 在不人工啟動程序的情況下對Config Client 的配置進行刷新。
server:
port :8769
spring :
cloud :
config :
server:
git:
uri: https://github.com/forezp/SpringcloudConfig
searchPaths: respo
username: miles02 @163.com
password :
label : master
application:
name : config-server
其中, uri 為遠程Git 倉庫的地址, serachPaths 為搜索遠程倉庫的文件夾地址, usemame和passwor d 為Git 倉庫的登錄名和密碼。如果是私人Git 倉庫,登錄名和密碼是必須的;如果是公開的Git 倉庫,可以不需要。label 為git 倉庫的分支名。
口搭建高可用Co nfig Server 集群。
當服務實例很多時,所有的服務實例需要同時從配置中心
Config Server 讀取配置文件,這時可以考慮將配置中心Config Server 做成一個微服務,並且將
其集群化,從而達到高可用。
口使用Spring Cloud Bus 刷新配置。
Spring Cloud Bus 是用輕量的消息代理將分布式的節點連接起來,可以用於廣播配置文件
的更改或者服務的監控管理。)個關鍵的思想就是,消息總線可以為微服務做監控,也可以實
現應用程序之間相I T-L 通信。S pring Cloud Bus 可選的消息代理組建包括RabbitMQ 、AMQP 和
Kafka 等。本節講述的是用RabbitMQ 作為Spring Cloud 的消息組件去刷新更改微服務的配置
文件。
九、服務鏈路追蹤
分布式配置中心S pring Cloud Config
口Config Server 從本地讀取配置文件。
spring:
cloud :
config :
server :
native :
search-locations: classpath : /shared
profiles :
active : native
application :
name : config- server
server :
port : 8769
Config Server 可以從本地倉庫讀取配置文件,也可以從遠處Git 倉庫讀取。本地倉庫是指
將所有的配置文件統一寫在Config Server 工程目錄下。Config Sever 暴露HttpAPI 接口, Config
Client 通過調用Config Sever 的H即API 接口來讀取配置文件。
為了講解得更清楚,本章將不在之前章節的工程的基礎上改造,而是重新建工程。和之前的工程一樣,采用多Mo dule 形式。
口Config Server 從遠程Git 倉庫讀取配置文件。
spring :
application :
name : config-client
cloud :
config :
uri: http : //localhost : 8769
fail-fast : true
profi les :
active : dev
Spring Cloud Config 支持從遠程Git 倉庫讀取配置文件,即Config Server 可以不從本地的
倉庫讀取,而是從遠程Git 倉庫讀取。這樣做的好處就是將配置統一管理,並且可以通過Spring
Cloud Bus 在不人工啟動程序的情況下對Config Client 的配置進行刷新。本例采用GitHub 作為
遠程Git 倉庫。
口搭建高可用Config Server 集群。
當服務實例很多時,所有的服務實例需要同時從配置中心
Config Server 讀取配置文件,這時可以考慮將配置中心Config Server 做成一個微服務,並且將
其集群化,從而達到高可用。配置中心C onfig Server 高可用的架構圖如圖10-1 所示。C onfig
Server 和Config Client 向Eureka Server 註冊,且將Config Server 多實例集群部署。
口使用Spring Cloud Bus 刷新配置。
Spring Cloud Bus 是用輕量的消息代理將分布式的節點連接起來,可以用於廣播配置文件
的更改或者服務的監控管理。)個關鍵的思想就是,消息總線可以為微服務做監控,也可以實現應用程序之間相I T-L 通信。S pring Cloud Bus 可選的消息代理組建包括RabbitMQ 、AMQP 和
Kafka 等。本節講述的是用RabbitMQ 作為Spring Cloud 的消息組件去刷新更改微服務的配置
文件。
如果有幾十個微服務,而每一個服務又是多實例,當更改配置時,需要重新啟動多個微服
務實例,會非常麻煩。Spring Cloud Bus 的一個功能就是讓這個過程變得簡單,當遠程Git 倉
庫的配置更改後,只需要向某一個微服務實例發送一個Post 請求,通過消息組件通知其他微
服務實例重新拉取配置文件。如圖10-3 所示,當遠程Git 倉庫的配置更改後,通過發送
“ /bus/refresh ” Post 請求給某一個微服務實例,通過消息組件,通知其他微服務實例,更新配
置文件。
十、微服務監控
十一、SpringSecurity
深入理解SpringCloud與微服務構建