微服務開發(fā)之Spring Cloud

1. 什么是 spring boot?

Spring Boot提供了一種新的編程范式,能在最小的阻力下開發(fā)Spring應用程序。有了它, 你可以更加敏捷地開發(fā)Spring應用程序,專注于應用程序的功能,不用在Spring的配置上多花功 夫,甚至完全不用配置。實際上,Spring Boot的一項重要工作就是讓Spring配置不再成為你成功路上的絆腳石。

2. 為什么要用 spring boot?

開發(fā)快。
Spring Boot使用“習慣優(yōu)于配置”的理念讓項目快速運行起來。使用Spring Boot很容易創(chuàng)建一個獨立運行、準生產級別的基于Spring框架的項目,使用Spring Boot你可以不用或則只需要很少的Spring配置。

3. spring boot 核心配置文件是什么?

SpringBoot的核心配置文件有application和bootstarp配置文件。

3.1 用途

(1) application文件主要用于Springboot自動化配置文件。
(2) bootstarp文件主要有以下幾種用途:
· 使用Spring Cloud Config注冊中心時,需要在bootStarp配置文件中添加鏈接到配置中心的配置屬性來加載外部配置中心的配置信息;
· 一些固定的不能被覆蓋的屬性;
· 一些加密/解密的場景;

3.2 都有什么格式?

· .properties 和 .yml
· .yml采取的是縮進的格式 不支持@PeopertySource注解導入配置,但是可以通過@Value("${}")導入配置

4. spring boot 配置文件有哪幾種類型?它們有什么區(qū)別?

在 Spring Boot 中有以下兩種配置文件
· bootstrap (.yml 或者 .properties)
boostrap 由父 ApplicationContext 加載,比 applicaton 優(yōu)先加載
boostrap 里面的屬性不能被覆蓋
· application (.yml 或者 .properties)
應用場景:
· application
主要用于 Spring Boot 項目的自動化配置(stg,dev,test)
· bootstrap
· 使用 Spring Cloud Config 配置中心時,這時需要在 bootstrap 配置文件中添加連接到配置中心的配置屬性來加載外部配置中心的配置信息;
· 一些固定的不能被覆蓋的屬性
· 一些加密/解密的場景

5. spring boot 有哪些方式可以實現(xiàn)熱部署?

熱部署:

大家都知道在項目開發(fā)過程中,常常會改動頁面數據或者修改數據結構,為了顯示改動效果,往往需要重啟應用查看改變效果,其實就是重新編譯生成了新的 Class 文件,這個文件里記錄著和代碼等對應的各種信息,然后 Class 文件將被虛擬機的 ClassLoader 加載。

而熱部署正是利用了這個特點,它監(jiān)聽到如果有 Class 文件改動了,就會創(chuàng)建一個新的 ClaassLoader 進行加載該文件,經過一系列的過程,最終將結果呈現(xiàn)在我們眼前

Spring boot通過使用 Spring Loaded和使用spring-boot-devtools進行熱部署。

6. 什么是 spring cloud?

Spring Cloud是一個微服務框架,相比Dubbo等RPC框架, Spring Cloud提供的全套的分布式系統(tǒng)解決方案。

Spring Cloud對微服務基礎框架Netflix的多個開源組件進行了封裝,同時又實現(xiàn)了和云端平臺以及和Spring Boot開發(fā)框架的集成。

Spring Cloud為微服務架構開發(fā)涉及的配置管理,服務治理,熔斷機制,智能路由,微代理,控制總線,一次性token,全局一致性鎖,leader選舉,分布式session,集群狀態(tài)管理等操作提供了一種簡單的開發(fā)方式。

Spring Cloud 為開發(fā)者提供了快速構建分布式系統(tǒng)的工具,開發(fā)者可以快速的啟動服務或構建應用、同時能夠快速和云平臺資源進行對接。

7. spring cloud 的核心組件有哪些?

1. Spring Cloud Eureka

我們使用微服務,微服務的本質還是各種API接口的調用,那么我們怎么產生這些接口、產生了這些接口之后如何進行調用那?如何進行管理哪?

答案就是Spring Cloud Eureka,我們可以將自己定義的API 接口注冊到Spring Cloud Eureka上,Eureka負責服務的注冊于發(fā)現(xiàn),如果學習過Zookeeper的話,就可以很好的理解,Eureka的角色和 Zookeeper的角色差不多,都是服務的注冊和發(fā)現(xiàn),構成Eureka體系的包括:服務注冊中心、服務提供者、服務消費者。

2. Spring Cloud Ribbon

在上Spring Cloud Eureka描述了服務如何進行注冊,注冊到哪里,服務消費者如何獲取服務生產者的服務信息,但是Eureka只是維護了服務生產者、注冊中心、服務消費者三者之間的關系,真正的服務消費者調用服務生產者提供的數據是通過Spring Cloud Ribbon來實現(xiàn)的。
在(1)中提到了服務消費者是將服務從注冊中心獲取服務生產者的服務列表并維護在本地的,這種客戶端發(fā)現(xiàn)模式的方式是服務消費者選擇合適的節(jié)點進行訪問服務生產者提供的數據,這種選擇合適節(jié)點的過程就是Spring Cloud Ribbon完成的。

Spring Cloud Ribbon客戶端負載均衡器由此而來。

3. Spring Cloud Feign

上述(1)、(2)中我們已經使用最簡單的方式實現(xiàn)了服務的注冊發(fā)現(xiàn)和服務的調用操作,如果具體的使用Ribbon調用服務的話,你就可以感受到使用Ribbon的方式還是有一些復雜,因此Spring Cloud Feign應運而生。

Spring Cloud Feign 是一個聲明web服務客戶端,這使得編寫Web服務客戶端更容易,使用Feign 創(chuàng)建一個接口并對它進行注解,它具有可插拔的注解支持包括Feign注解與JAX-RS注解,F(xiàn)eign還支持可插拔的編碼器與解碼器,Spring Cloud 增加了對 Spring MVC的注解,Spring Web 默認使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的負載均衡的HTTP客戶端 Feign。

簡單的可以理解為:Spring Cloud Feign 的出現(xiàn)使得Eureka和Ribbon的使用更為簡單。

4. Spring Cloud Hystrix

我們在(1)、(2)、(3)中知道了使用Eureka進行服務的注冊和發(fā)現(xiàn),使用Ribbon實現(xiàn)服務的負載均衡調用,還知道了使用Feign可以簡化我們的編碼。但是,這些還不足以實現(xiàn)一個高可用的微服務架構。

例如:當有一個服務出現(xiàn)了故障,而服務的調用方不知道服務出現(xiàn)故障,若此時調用放的請求不斷的增加,最后就會等待出現(xiàn)故障的依賴方 相應形成任務的積壓,最終導致自身服務的癱瘓。

Spring Cloud Hystrix正是為了解決這種情況的,防止對某一故障服務持續(xù)進行訪問。Hystrix的含義是:斷路器,斷路器本身是一種開關裝置,用于我們家庭的電路保護,防止電流的過載,當線路中有電器發(fā)生短路的時候,斷路器能夠及時切換故障的電器,防止發(fā)生過載、發(fā)熱甚至起火等嚴重后果

5. Spring Cloud Config

對于微服務還不是很多的時候,各種服務的配置管理起來還相對簡單,但是當成百上千的微服務節(jié)點起來的時候,服務配置的管理變得會復雜起來。

分布式系統(tǒng)中,由于服務數量巨多,為了方便服務配置文件統(tǒng)一管理,實時更新,所以需要分布式配置中心組件。在Spring Cloud中,有分布式配置中心組件Spring Cloud Config ,它支持配置服務放在配置服務的內存中(即本地),也支持放在遠程Git倉庫中。在Cpring Cloud Config 組件中,分兩個角色,一是Config Server,二是Config Client。

Config Server用于配置屬性的存儲,存儲的位置可以為Git倉庫、SVN倉庫、本地文件等,Config Client用于服務屬性的讀取。

6. Spring Cloud Zuul

我們使用Spring Cloud Netflix中的Eureka實現(xiàn)了服務注冊中心以及服務注冊與發(fā)現(xiàn);而服務間通過Ribbon或Feign實現(xiàn)服務的消費以及均衡負載;通過Spring Cloud Config實現(xiàn)了應用多環(huán)境的外部化配置以及版本管理。為了使得服務集群更為健壯,使用Hystrix的融斷機制來避免在微服務架構中個別服務出現(xiàn)異常時引起的故障蔓延。

先來說說這樣架構需要做的一些事兒以及存在的不足:

1、首先,破壞了服務無狀態(tài)特點。為了保證對外服務的安全性,我們需要實現(xiàn)對服務訪問的權限控制,而開放服務的權限控制機制將會貫穿并污染整個開放服務的業(yè)務邏輯,這會帶來的最直接問題是,破壞了服務集群中REST API無狀態(tài)的特點。從具體開發(fā)和測試的角度來說,在工作中除了要考慮實際的業(yè)務邏輯之外,還需要額外可續(xù)對接口訪問的控制處理。

2、其次,無法直接復用既有接口。當我們需要對一個即有的集群內訪問接口,實現(xiàn)外部服務訪問時,我們不得不通過在原有接口上增加校驗邏輯,或增加一個代理調用來實現(xiàn)權限控制,無法直接復用原有的接口。
面對類似上面的問題,我們要如何解決呢?下面進入本文的正題:服務網關!

為了解決上面這些問題,我們需要將權限控制這樣的東西從我們的服務單元中抽離出去,而最適合這些邏輯的地方就是處于對外訪問最前端的地方,我們需要一個更強大一些的均衡負載器,它就是本文將來介紹的:服務網關。

服務網關是微服務架構中一個不可或缺的部分。通過服務網關統(tǒng)一向外系統(tǒng)提供REST API的過程中,除了具備服務路由、均衡負載功能之外,它還具備了權限控制等功能。Spring Cloud Netflix中的Zuul就擔任了這樣的一個角色,為微服務架構提供了前門保護的作用,同時將權限控制這些較重的非業(yè)務邏輯內容遷移到服務路由層面,使得服務集群主體能夠具備更高的可復用性和可測試性


圖片.png

7. Spring Cloud Bus

在(5)Spring Cloud Config中,我們知道的配置文件可以通過Config Server存儲到Git等地方,通過Config Client進行讀取,但是我們的配置文件不可能是一直不變的,當我們的配置文件放生變化的時候如何進行更新哪?

一種最簡單的方式重新一下Config Client進行重新獲取,但Spring Cloud絕對不會讓你這樣做的,Spring Cloud Bus正是提供一種操作使得我們在不關閉服務的情況下更新我們的配置。

Spring Cloud Bus官方意義:消息總線。
當然動態(tài)更新服務配置只是消息總線的一個用處,還有很多其他用處


圖片.png

8. spring cloud 斷路器的作用是什么?

在微服務架構中,存在著那么多的服務單元,若一個單元出現(xiàn)故障,就會因依賴關系形成故障蔓延,最終導致整個系統(tǒng)的癱瘓,這樣的架構相較傳統(tǒng)架構就更加的不穩(wěn)定。為了解決這樣的問題,因此產生了斷路器模式

斷路器模式源于Martin Fowler的Circuit Breaker一文。“斷路器”本身是一種開關裝置,用于在電路上保護線路過載,當線路中有電器發(fā)生短路時,“斷路器”能夠及時的切斷故障電路,防止發(fā)生過載、發(fā)熱、甚至起火等嚴重后果。

在分布式架構中,斷路器模式的作用也是類似的,當某個服務單元發(fā)生故障(類似用電器發(fā)生短路)之后,通過斷路器的故障監(jiān)控(類似熔斷保險絲),向調用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間占用不釋放,避免了故障在分布式系統(tǒng)中的蔓延。

在Spring Cloud中使用了Hystrix 來實現(xiàn)斷路器的功能,Hystrix在運行過程中會向每個commandKey對應的熔斷器報告成功、失敗、超時和拒絕的狀態(tài),熔斷器(Circuit Breaker)維護并統(tǒng)計這些數據,并根據這些統(tǒng)計信息來決策熔斷開關是否打開。如果打開,熔斷后續(xù)請求,快速返回。隔一段時間(默認是5s)之后熔斷器嘗試半開,放入一部分流量請求進來,相當于對依賴服務進行一次健康檢查,如果請求成功,熔斷器關閉

9. springcloud 和dubbo區(qū)別

springcloud為啥默認使用restful 方式,而不是RPC方式

使用Dubbo的RPC來實現(xiàn)服務間調用的一些痛點:

服務提供方與調用方接口依賴方式太強:我們?yōu)槊總€微服務定義了各自的service抽象接口,并通過持續(xù)集成發(fā)布到私有倉庫中,調用方應用對微服務提供的抽象接口存在強依賴關系,因此不論開發(fā)、測試、集成環(huán)境都需要嚴格的管理版本依賴,才不會出現(xiàn)服務方與調用方的不一致導致應用無法編譯成功等一系列問題,以及這也會直接影響本地開發(fā)的環(huán)境要求,往往一個依賴很多服務的上層應用,每天都要更新很多代碼并install之后才能進行后續(xù)的開發(fā)。
若沒有嚴格的版本管理制度或開發(fā)一些自動化工具,這樣的依賴關系會成為開發(fā)團隊的一大噩夢。
而REST接口相比RPC更為輕量化,服務提供方和調用方的依賴只是依靠一紙契約,不存在代碼級別的強依賴,當然REST接口也有痛點,因為接口定義過輕,很容易導致定義文檔與實際實現(xiàn)不一致導致服務集成時的問題,但是該問題很好解決,只需要通過每個服務整合swagger,讓每個服務的代碼與文檔一體化,就能解決。所以在分布式環(huán)境下,REST方式的服務依賴要比RPC方式的依賴更為靈活。

服務對平臺敏感,難以簡單復用:通常我們在提供對外服務時,都會以REST的方式提供出去,這樣可以實現(xiàn)跨平臺的特點,任何一個語言的調用方都可以根據接口定義來實現(xiàn)。那么在Dubbo中我們要提供REST接口時,不得不實現(xiàn)一層代理,用來將RPC接口轉換成REST接口進行對外發(fā)布。若我們每個服務本身就以REST接口方式存在,當要對外提供服務時,只要在API網關中配置映射關系和權限控制就可實現(xiàn)服務的復用了。
相信這些痛點也是為什么當當網在dubbox(基于Dubbo的開源擴展)中增加了對REST支持的原因之一。

當然,springcloud 也支持使用RPC,比如gRPC(谷歌開源),https://github.com/yidongnan/grpc-spring-boot-starter/blob/master/README-zh.md

使用gRpc最大的好處,是其性能非常高(通信采用Netty),會比采用rustful性能高一倍(因為),通過proto文件定義的接口也是非常清晰而又靈活

10. springcloud中,從前端發(fā)起一個請求后需要經過哪些組件

這個問題,和springcloud有哪些組件,作用是啥差不多
** Eureka:各個服務啟動時,Eureka Client都會將服務注冊到Eureka Server,并且Eureka Client還可以反過來從Eureka Server拉取注冊表,從而知道其他服務在哪里
** Ribbon
:服務間發(fā)起請求的時候,基于Ribbon做負載均衡,從一個服務的多臺機器中選擇一臺
Feign:基于Feign的動態(tài)代理機制,根據注解和選擇的機器,拼接請求URL地址,發(fā)起請求
Hystrix:發(fā)起請求是通過Hystrix的線程池來走的,不同的服務走不同的線程池,實現(xiàn)了不同服務調用的隔離,避免了服務雪崩的問題
Zuul:如果前端、移動端要調用后端系統(tǒng),統(tǒng)一從Zuul網關進入,由Zuul網關轉發(fā)請求給對應的服務
config 服務配置中心
zipkin 服務調用鏈監(jiān)控中心
turbine 服務斷路器監(jiān)控

圖片.png

圖片.png

前提條件:服務注冊和服務發(fā)現(xiàn)
1、微服務A啟動時,Eureka client把服務注冊到eureka server上;
2、微服務B通過Eurek client到eureka server把與其相關的服務地址表拉取下來
過程:假如是從前端先調用服務B,然后服務B調用服務A
1、zuul,網關,如果前端、移動端要調用后端系統(tǒng),統(tǒng)一從Zuul網關進入,由Zuul網關轉發(fā)請求給對應的服務B(經過網關后,可以再經過一個nginx做路由),在zuul中可以配置請求url與微服務的對應關系(通常是這個微服務的名稱),然后根據名稱從本地注冊表找到這個服務所在的地址

2、ribbon,負載均衡,在服務B調用服務A時(服務A部署了多個節(jié)點、多個ip),先通過ribbon獲取到本次要調用服務A的ip地址

3、feign,動態(tài)構建http請求,在通過ribbon獲取到服務A的IP地址后,通過feign夠建http請求,包括 ip、端口、請求參數、請求方法

4、Hystrix,熔斷、隔離、降級,在feign構建好http請求后, 通過Hystrix線程池調用服務A中的接口方法。在hystrix中,可以配置服務熔斷規(guī)則,以及熔斷后的處理方法(也就是所謂降級,通常會做一下日志記錄)。
通過hystrix線程池可以隔離不同服務調用;
通過配置熔斷規(guī)則可以保證在服務不可用或者不穩(wěn)定時,快速返回結果,而不是每次都等待超時;
通過設置服務熔斷之后的處理方法,來進行服務降級;

11. Spring cloud 項目中遇到的問題

https://blog.csdn.net/zhangjq520/article/details/89448901
https://www.cnblogs.com/dgcjiayou/articles/9591253.html

問題一:用戶充值記錄有時候莫名其妙存在充值后的重復數據記錄。

原因:Ribbon重試
負載均衡Ribbon發(fā)現(xiàn)遠程請求實例不可到達之后,去重試其他實例的過程。那么當有些服務在執(zhí)行過程中由于各種原因導致超時,feign client的重試就會導致接口重復執(zhí)行;所有只有查詢可以重試,但是其他的可以能帶來冪等性問題的接口是要關閉重試的

問題二:Eureka注冊服務慢

原因:心跳為30S
解決方式:修改心跳時間(開發(fā)環(huán)境可以使用,生產環(huán)境推薦使用默認值)
服務注冊涉及到周期性心跳,默認30秒一次(通過客戶端配置的serviceUrl)。只有當實例、服務器端和客戶端的本地緩存中的元數據都相同時,服務才能被其他客戶端發(fā)現(xiàn)(所以可能需要3次心跳)

問題三:已停止的微服務節(jié)點注銷慢或者不注銷

在開發(fā)測試環(huán)境下,常常希望Eureka server能迅速有效地注銷已停止的微服務實例,然而由于Eureka Server清理無效節(jié)點周期長(默認90s),以及自我保護模式等,可能會遇到已停止的微服務節(jié)點注銷慢或者甚至不注銷的問題
解決辦法:

  1. Eureka Server端:關閉自我保護,并且按需配置清理無效節(jié)點的時間間隔(默認90s)
  2. Eureka Client端:開啟健康檢查,并按需配置續(xù)約更新時間和到期時間(默認都是30s)
注意:這些配置僅建議在開發(fā)或者測試使用,生產環(huán)境還是堅持使用默認值。

問題四:Ribbon/Feign整合Hystrix后首次請求失敗

在某些場景下,F(xiàn)eign或Ribbon整合Hystrix后,會出現(xiàn)首次調用失敗的問題
原因:Hystrix默認的超時時間是一秒,如果在1秒內得不到響應,就會進入fallback邏輯。由于Spring的懶加載機制,首次請求往往會比較慢,因此在某些機器(特別是配置低的機器)上,首次請求需要的時間可能就會大于1秒。
解決辦法:(一)延長Hystrix的超時時間 (二):禁用Hystrix的超時

12. Eureka原理,底層實現(xiàn)

12.1 架構:

圖片.png

從圖中可以看出 Eureka Server 集群相互之間通過 Replicate 來同步數據,相互之間不區(qū)分主節(jié)點和從節(jié)點,所有的節(jié)點都是平等的。在這種架構中,節(jié)點通過彼此互相注冊來提高可用性,每個節(jié)點需要添加一個或多個有效的 serviceUrl 指向其他節(jié)點。

如果某臺 Eureka Server 宕機,Eureka Client 的請求會自動切換到新的 Eureka Server 節(jié)點。當宕機的服務器重新恢復后,Eureka 會再次將其納入到服務器集群管理之中。當節(jié)點開始接受客戶端請求時,所有的操作都會進行節(jié)點間復制,將請求復制到其所知的所有Eureka Server節(jié)點中。

另外 Eureka Server 的同步遵循著一個非常簡單的原則:只要有一條邊將節(jié)點連接,就可以進行信息傳播與同步。所以,如果存在多個節(jié)點,只需要將節(jié)點之間兩兩連接起來形成通路,那么其它注冊中心都可以共享信息。每個 Eureka Server 同時也是 Eureka Client,多個 Eureka Server 之間通過 P2P 的方式完成服務注冊表的同步。
Eureka Server 集群之間的狀態(tài)是采用異步方式同步的,所以不保證節(jié)點間的狀態(tài)一定是一致的,不過基本能保證最終狀態(tài)是一致的。

12.2 工作流程:

1、Eureka Server 啟動成功,等待服務端注冊。在啟動過程中如果配置了集群,集群之間定時通過 Replicate 同步注冊表,每個 Eureka Server 都存在獨立完整的服務注冊表信息
2、Eureka Client 啟動時根據配置的 Eureka Server 地址去注冊中心注冊服務
3、Eureka Client 會每 30s 向 Eureka Server 發(fā)送一次心跳請求,證明客戶端服務正常
4、當 Eureka Server 90s 內沒有收到 Eureka Client 的心跳,注冊中心則認為該節(jié)點失效,會注銷該實例
5、單位時間內 Eureka Server 統(tǒng)計到有大量的 Eureka Client 沒有上送心跳,則認為可能為網絡異常,進入自我保護機制,不再剔除沒有上送心跳的客戶端
6、當 Eureka Client 心跳請求恢復正常之后,Eureka Server 自動退出自我保護模式
7、Eureka Client 定時全量或者增量從注冊中心獲取服務注冊表,并且將獲取到的信息緩存到本地
8、服務調用時,Eureka Client 會先從本地緩存找尋調取的服務。如果獲取不到,先從注冊中心刷新注冊表,再同步到本地緩存
9、Eureka Client 獲取到目標服務器信息,發(fā)起服務調用
10、Eureka Client 程序關閉時向 Eureka Server 發(fā)送取消請求,Eureka Server 將實例從注冊表中刪除

12.3 Eureka 與 Zookeeper區(qū)別

Eureka Server 各個節(jié)點都是平等的,幾個節(jié)點掛掉不會影響正常節(jié)點的工作,剩余的節(jié)點依然可以提供注冊和查詢服務。而 Eureka Client 在向某個 Eureka 注冊時,如果發(fā)現(xiàn)連接失敗,則會自動切換至其它節(jié)點。只要有一臺 Eureka Server 還在,就能保證注冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。

cureka是AP,zookeeper是CP;

12.4 Eureka 實現(xiàn)最終一致性——消息廣播

· 1. Eureka Server 管理了全部的服務器列表(PeerEurekaNodes)。
· 2. 當 Eureka Server 收到客戶端的注冊、下線、心跳請求時,通過 PeerEurekaNode 向其余的服務器進行消息廣播,如果廣播失敗則重試,直到任務過期后取消任務,此時這兩臺服務器之間數據會出現(xiàn)短暫的不一致。
注意: 雖然消息廣播失敗,但只要收到客戶端的心跳,仍會向所有的服務器(包括失聯(lián)的服務器)廣播心跳任務。
· 3. 如果網絡恢復正常,收到了其它服務器廣播的心跳任務,此時可能有三種情況:
一是腦裂很快恢復,一切正常;
二是該實例已經自動過期,則重新進行注冊;
三是數據沖突,出現(xiàn)不一致的情況,則需要發(fā)起同步請求,其實也就是重新注冊一次,同時踢除老的實例。
總之,通過集群之間的消息廣播可以實現(xiàn)數據的最終一致性。

12.5 自我保護機制

默認情況下,如果 Eureka Server 在一定的 90s 內沒有接收到某個微服務實例的心跳,會注銷該實例。但是在微服務架構下服務之間通常都是跨進程調用,網絡通信往往會面臨著各種問題,比如微服務狀態(tài)正常,網絡分區(qū)故障,導致此實例被注銷。

固定時間內大量實例被注銷,可能會嚴重威脅整個微服務架構的可用性。為了解決這個問題,Eureka 開發(fā)了自我保護機制,那么什么是自我保護機制呢?

Eureka Server 在運行期間會去統(tǒng)計心跳失敗比例在 15 分鐘之內是否低于 85%,如果低于 85%,Eureka Server 即會進入自我保護機制。Eureka Server 觸發(fā)自我保護機制后,頁面會出現(xiàn)提示。

Eureka Server 進入自我保護機制,會出現(xiàn)以下幾種情況:
(1 Eureka 不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務
(2 Eureka 仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其它節(jié)點上(即保證當前節(jié)點依然可用)
(3 當網絡穩(wěn)定時,當前實例新的注冊信息會被同步到其它節(jié)點中
Eureka 自我保護機制是為了防止誤殺服務而提供的一個機制。當個別客戶端出現(xiàn)心跳失聯(lián)時,則認為是客戶端的問題,剔除掉客戶端;當 Eureka 捕獲到大量的心跳失敗時,則認為可能是網絡問題,進入自我保護機制;當客戶端心跳恢復時,Eureka 會自動退出自我保護機制。

如果在保護期內剛好這個服務提供者非正常下線了,此時服務消費者就會拿到一個無效的服務實例,即會調用失敗。對于這個問題需要服務消費者端要有一些容錯機制,如重試,斷路器等。

通過在 Eureka Server 配置參數,開啟或者關閉保護機制,生產環(huán)境建議打開。

13. Hystrix原理,底層實現(xiàn)

13.1 Hystrix設計目標

· 對來自依賴的延遲和故障進行防護和控制——這些依賴通常都是通過網絡訪問的
· 阻止故障的連鎖反應
· 快速失敗并迅速恢復
· 回退并優(yōu)雅降級
· 提供近實時的監(jiān)控與告警

13.2 Hystrix如何實現(xiàn)這些設計目標

· 使用命令模式將所有對外部服務(或依賴關系)的調用包裝在HystrixCommand或HystrixObservableCommand對象中,并將該對象放在單獨的線程中執(zhí)行;
· 每個依賴都維護著一個線程池(或信號量),線程池被耗盡則拒絕請求(而不是讓請求排隊);
· 記錄請求成功,失敗,超時和線程拒絕。
· 服務錯誤百分比超過了閾值,熔斷器開關自動打開,一段時間內停止對該服務的所有請求。
· 請求失敗,被拒絕,超時或熔斷時執(zhí)行降級邏輯。
· 近實時地監(jiān)控指標和配置的修改。

13.3 Hystrix處理流程

圖片.png

Hystrix整個工作流如下:
· 1.構建Hystrix的Command對象, 調用執(zhí)行方法.
· 2.Hystrix檢查當前服務的熔斷器開關是否開啟, 若開啟, 則執(zhí)行降級服務getFallback方法.
· 3.若熔斷器開關關閉, 則Hystrix檢查當前服務的線程池是否能接收新的請求, 若超過線程池已滿, 則執(zhí)行降級服務getFallback方法.
· 4.若線程池接受請求, 則Hystrix開始執(zhí)行服務調用具體邏輯run方法.
· 5.若服務執(zhí)行失敗, 則執(zhí)行降級服務getFallback方法, 并將執(zhí)行結果上報HystrixCommandMetrics(HystrixCircuitBreaker斷路器中參數)更新服務健康狀況.
· 6.若服務執(zhí)行超時, 則執(zhí)行降級服務getFallback方法, 并將執(zhí)行結果上報HystrixCommandMetrics(HystrixCircuitBreaker斷路器中參數)更新服務健康狀況.
· 7.若服務執(zhí)行成功, 返回正常結果.
· 8.若服務降級方法getFallback執(zhí)行成功, 則返回降級結果.
· 9.若服務降級方法getFallback執(zhí)行失敗, 則拋出異常.

14. 分布式配置——Spring Cloud Config原理

作為一個開發(fā)而言,知道每個項目都有其需要維護的配置文件,如果項目量小而言,以人力尚可以接受。項目量一但增多,傳統(tǒng)的維護方式就變的困難,所以需要一個統(tǒng)一的配置中心來維護所有服務的配置文件。再言,傳統(tǒng)的項目配置文件配置數據發(fā)生改變,需要重啟服務使其生效,spring cloud config 可以不需要進行重啟對應的服務。

Spring Cloud Config用來為分布式系統(tǒng)中的基礎設施和微服務應用提供集中化的外部配置支持。

服務端:分布式配置中心,獨立的微服務應用,用來連接配置倉庫(GIT)并為客戶端提供獲取配置信息、加密/解密等訪問接口。、
客戶端:微服務架構中各個微服務應用和基礎設施,通過指定配置中心管理應用資源與業(yè)務相關的配置內容,啟動時從配置中心獲取和加載配置信息

14.1 架構

圖片.png
架構模塊介紹

遠程GIT倉庫:用來存儲配置文件的地方;

Config Server:分布式配置中心,微服務中指定了連接倉庫的位置以及賬號密碼等信息;

本地GIT倉庫:在Config Server文件系統(tǒng)中,客戶單每次請求獲取配置信息時,Config Server從GIT倉庫獲取最新配置到本地,然后在本地GIT倉庫讀取并返回。當遠程倉庫無法獲取時,直接將本地倉庫內容返回;

ServerA/B:具體的微服務應用,他們指定了Config Server地址,從而實現(xiàn)外部化獲取應用自己想要的配置信息。應用啟動時會向Config Server發(fā)起請求獲取配置信息進行加載;

消息中心:上述架構圖是基于消息總線spring cloud bus的方式,依賴的外部的MQ組件,目前支持kafka、rabbitmq。通過Config Server配置中心提供的/bus/refresh endpoint作為生產者發(fā)送消息,客戶端接受到消息通過http接口形式從Config Server拉取配置;

服務注冊中心:可以將Config Server注冊到服務注冊中心上比如Eureka,然后客戶端通過服務注冊中心發(fā)現(xiàn)Config Server服務列表,選擇其中一臺Config Server來完成健康檢查以及獲取遠端配置信息;

14.2 Spring Cloud Config客戶端加載流程

客戶端應用從配置管理中獲取配置執(zhí)行流程:

1、應用啟動時,根據bootstrap.yml中配置的應用名{application}、環(huán)境名{profile}、分支名{label},向Config Server請求獲取配置信息;
2、Config Server根據自己維護的GIT倉庫信息與客戶端傳過來的配置定位去查找配置信息;
3、通過git clone命令將找到的配置下載到Config Server的文件系統(tǒng)(本地GIT倉庫);
4、Config Server創(chuàng)建Spring的ApplicationContext實例,并從GIT本地倉庫中加載配置文件,最后讀取這些配置內容返回給客戶端應用;
5、客戶端應用在獲取外部配置內容后加載到客戶端的ApplicationContext實例,該配置內容優(yōu)先級高于客戶端Jar包內部的配置內容,所以在Jar包中重復的內容將不再被加載;

15. Zuul原理

zuul 是netflix開源的一個API Gateway 服務器, 本質上是一個web servlet應用。
Zuul 在云平臺上提供動態(tài)路由,監(jiān)控,彈性,安全等邊緣服務的框架。Zuul 相當于是設備和 Netflix 流應用的 Web 網站后端所有請求的前門。


圖片.png

一個請求過來后,經過DispatchServlet,zuulHadlerMapping,ZuulController(調用ZuulServlet,在ZuulServlet中加載過濾器),
在pre類型Filters中的PriDecorationFilter中把源請求url轉換拼接(路由)為目標url,然后經過Routing類型的Filters請求目標url。
zuul配置文件中設置path和serverId后,zuul啟動后是加載到map中的。

15.1 過濾器

zuul的核心是一系列的filters, 其作用可以類比Servlet框架的Filter,或者AOP。

zuul把Request route到 用戶處理邏輯 的過程中,這些filter參與一些過濾處理,比如Authentication,Load Shedding等。


圖片.png

Zuul的過濾器是由Groovy寫成,這些過濾器文件被放在Zuul Server上的特定目錄下面,Zuul會定期輪詢這些目錄,修改過的過濾器會動態(tài)的加載到Zuul Server中以便過濾請求使用。

Zuul大部分功能都是通過過濾器來實現(xiàn)的。Zuul中定義了四種標準過濾器類型,這些過濾器類型對應于請求的典型生命周期。

PRE:這種過濾器在請求被路由之前調用。我們可利用這種過濾器實現(xiàn)身份驗證、在集群中選擇請求的微服務、記錄調試信息等。

ROUTING:這種過濾器將請求路由到微服務。這種過濾器用于構建發(fā)送給微服務的請求,并使用Apache HttpClient或Netfilx Ribbon請求微服務。

POST:這種過濾器在路由到微服務以后執(zhí)行。這種過濾器可用來為響應添加標準的HTTP Header、收集統(tǒng)計信息和指標、將響應從微服務發(fā)送給客戶端等。

ERROR:在其他階段發(fā)生錯誤時執(zhí)行該過濾器。

16. Ribbon 架構,是怎么實現(xiàn)負載均衡的

Eureka與Ribbon整合工作原理


圖片.png

16.1 LoadBalancer--負載均衡器的核心

LoadBalancer 的職能主要有三個:
1.維護Sever實例列表的數量(新增、更新、刪除等)
2.維護Server實例列表的狀態(tài)(狀態(tài)更新)
3.當請求Server實例時,通過負載均衡規(guī)則IRule返回最合適的Server實例


作者:張凱_9908
鏈接:http://www.itdecent.cn/p/b4aac6681c83
來源:簡書

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容