SpringCloud開始的第二課(consul、Feign宣告式呼叫、Jmetter壓力測驗工具、Hystrix熔斷降級兜底、)
一、前提回顧
上文我們講解了(RestTemplate、Eureka、Eureka集群、Ribbon負載均衡、Eureka節點服務剔除)
上文鏈接
接下來我們繼續講講其他的微服務的知識示例
二、Eureka的替換方案
疑問:Eureka那么好用為什么要換掉它呢?
在Euraka的GitHub上,宣布Eureka 2.x閉源,近這意味著如果開發者繼續使用作為 2.x 分支上現有作業 repo 一部分發布的代碼庫和工件,則將自負風險,
那么我們可以替換哪些注冊中心呢?(如下)
| 組件名 | 語言 | CAP | 一致性演算法 | 服務健康檢查 | 對外暴露介面 |
|---|---|---|---|---|---|
| Eureka | JAVA | AP(可用性、磁區容忍性) | 無 | 可配支持 | HTTP |
| Consul | Go | CP(一致性、磁區容忍性) | Raft | 支持 | HTTP/DNS |
| Zookeeper | JAVA | CP(一致性、磁區容忍性) | Paxos | 支持 | 客戶端 |
| Nacos | JAVA | AP(可用性、磁區容忍性) | Raft | 支持 | HTTP |
三、什么是consul
本文我們講解下consul替代上文的eureka
consul是近幾年比較流行的服務發現工具,作業中用到,簡單了解一下,consul的三個主要應用場景: 服務發現、服務隔離、服務配置,
Consul 是 HashiCorp 公司推出的開源工具,用于實作分布式系統的服務發現與配置,與其它分布式服務注冊與發現的方案,Consul 的方案更“一站式”,內置了服務注冊與發現框 架、分布一致性協議實 現、健康檢查、Key/Value
存盤、多資料中心方案,不再需要依賴其它工具(比如 ZooKeeper 等), 使用起來也較 為簡單,
Consul 使用 Go 語言撰寫,因此具有天然可移植性(支持Linux、windows和 Mac OS X);安裝包僅包含一個可執行檔案,方便部署,與 Docker等輕量級容器可無縫配合,
Consul 的優勢:
- 使用 Raft 演算法來保證一致性, 比復雜的 Paxos 演算法更直接. 相比較而言, zookeeper 采用的是Paxos, 而 etcd 使用的則是 Raft,
- 支持多資料中心,內外網的服務采用不同的埠進行監聽, 多資料中心集群可以避免單資料中心
的單點故障,而其部署則需要考慮網路延遲, 分片等情況等, zookeeper 和 etcd 均不提供多資料中心功能的支持, - 支持健康檢查, etcd 不提供此功能,
- 支持 http 和 dns 協議介面, zookeeper 的集成較為復雜, etcd 只支持 http 協議,
- 官方提供 web 管理界面, etcd 無此功能,
綜合比較, Consul 作為服務注冊和配置管理的新星, 比較值得關注和研究,
特性:
- 服務發現
- 健康檢查
- Key/Value 存盤
- 多資料中心
四、consul與Eureka的區別
(1)一致性
-
Consul強一致性(CP)
- 服務注冊相比Eureka會稍慢一些,因為Consul的raft協議要求必須過半數的節點都寫入成功才認
為注冊成功 - Leader掛掉時,重新選舉期間整個consul不可用,保證了強一致性但犧牲了可用性,
- 服務注冊相比Eureka會稍慢一些,因為Consul的raft協議要求必須過半數的節點都寫入成功才認
-
Eureka保證高可用和最終一致性(AP)
- 服務注冊相對要快,因為不需要等注冊資訊replicate到其他節點,也不保證注冊資訊是否
replicate成功 - 當資料出現不一致時,雖然A, B上的注冊資訊不完全相同,但每個Eureka節點依然能夠正常對外提供服務,這會出現查詢服務資訊時如果請求A查不到,但請求B就能查到,如此保證了可用性但犧牲了一致性,
- 服務注冊相對要快,因為不需要等注冊資訊replicate到其他節點,也不保證注冊資訊是否
(2)開發語言和使用
- eureka就是個servlet程式,跑在servlet容器中
- Consul則是go撰寫而成,安裝啟動即可
五、consul的下載與安裝
Consul 不同于 Eureka 需要單獨安裝,訪問Consul 官網下載 Consul 的最新版本,我這里是consul1.5.3x,根據不同的系統型別選擇不同的安裝包,
(注意如果你是阿里云,請開放防火墻埠、安全組,如果有寶塔的話,記得也要開放寶塔的防火墻埠)
linux
## 從官網下載最新版本的Consul服務
wget https://releases.hashicorp.com/consul/1.5.3/consul_1.5.3_linux_amd64.zip
##使用unzip命令解壓
unzip consul_1.5.3_linux_amd64.zip
##將解壓好的consul可執行命令拷貝到/usr/local/bin目錄下
cp consul /usr/local/bin
##測驗一下
consul
啟動consul服務
0.0.0.0指允許任意ip訪問
##已開發者模式快速啟動,-client指定客戶端可以訪問的ip地址
[root@node01 ~]# consul agent -dev -client=0.0.0.0
==> Starting Consul agent...
Version: 'v1.5.3'
Node ID: '49ed9aa0-380b-3772-a0b6-b0c6ad561dc5'
Node name: 'node01'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: false)
Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false,
Auto-Encrypt-TLS: false
啟動成功之后訪問: http://IP:8500 ,可以看到 Consul 的管理界面

windows
下載解壓

- 雙擊啟動
- 打開cmd視窗至該consul.exe檔案目錄下,運行命令
consul agent -dev -client=0.0.0.0
- 然后訪問測驗下

六、consul的基本使用
Consul 支持健康檢查,并提供了 HTTP 和 DNS 呼叫的API介面完成服務注冊,服務發現,以及K/V存盤這些功能,接下來通過發送HTTP請求的形式來了解一下Consul
服務注冊與發現
- (1)注冊服務
通過postman發送put請求到http://localhost:8500/v1/catalog/register地址可以完成服務注冊
{
"Datacenter": "dc1",
"Node": "node01",
"Address": "192.168.74.102",
"Service": {
"ID":"mysql-01",
"Service": "mysql",
"tags": ["master","v1"],
"Address": "192.168.74.102",
"Port": 3306
}
}


-
服務注冊成功
-
(2)服務查詢
通過postman發送get請求到http://localhost:8500/v1/catalog/services查看所有的服務串列

- 通過postman發送get請求到http://localhost:8500/v1/catalog/service/服務名 查看具體的服務詳
情

- (3)服務洗掉
通過postman發送put請求到http://localhost:8500/v1/catalog/deregister洗掉服務(注意路徑不要結尾加 / )
{
"Datacenter": "dc1",
"Node": "node01",
"ServiceID": "mysql-01"
}
consul的KV存盤
可以參照Consul提供的KV存盤的API完成基于Consul的資料存盤(以下會舉例說明)
| 含義 | 請求路徑 | 請求方式 |
|---|---|---|
| 查看key | v1/kv/:key | GET |
| 保存或更新 | v1/kv/:key | put |
| 洗掉key | v1/kv/:key | delete |
-
key值中可以帶/, 可以看做是不同的目錄結構,
-
value的值經過了base64_encode,獲取到資料后base64_decode才能獲取到原始值,資料不能大
于512Kb -
不同資料中心的kv存盤系統是獨立的,使用dc=?引數指定
-
保存key

- 修改指定鍵值

- 查看key

- 可視化顯示

七、基于consul的服務注冊
引入依賴
注意:product專案、以及order專案都要引入(需要注冊和發現的微服務都要引入)
引入jar包的同時,注釋掉上述的eureka的jar包
<!--SpringCloud提供的基于Consul的服務發現-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!--actuator用于心跳檢查-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
其中 spring-cloud-starter-consul-discovery
是SpringCloud提供的對consul支持的相關依賴,
spring-boot-starter-actuator 適用于完成心跳檢測回應的相關依賴,(上文的eureka的安全檢測也依賴于這個啟動器)
更換組態檔

- 為了保留之前的eureka的配置
配置服務注冊
product微服務的yaml檔案(注意不需要資料庫的,不配置資料庫相關的配置)
server:
# 9011 9015
port: 9011 #埠
spring:
application:
name: ebuy-product #服務名稱
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/ebuy?useUnicode=true&characterEncoding=utf8
username: root
password: 123
cloud:
consul:
host: localhost
port: 8500
discovery:
register: true
instance-id: ${spring.application.name}-1
service-name: ${spring.application.name}
port: ${server.port}
health-check-path: /actuator/health
health-check-interval: 15s
prefer-ip-address: true
ip-address: ${spring.cloud.client.ip-address}
mybatis:
type-aliases-package: cn.ebuy.product.pojo
mapper-locations: cn/ebuy/product/pojo/*.xml
logging:
level:
cn.ebuy: DEBUG
- 配置consul部分

- 同樣order微服務進行配置

- 配置詳解
其中 spring.cloud.consul 中添加consul的相關配置 - host:表示Consul的Server的請求地址
- port:表示Consul的Server的埠
- discovery:服務注冊與發現的相關配置
- instance-id : 實體的唯一id(推薦必填),spring cloud官網檔案的推薦,為了保證生成一
個唯一的id ,也可以換成
- instance-id : 實體的唯一id(推薦必填),spring cloud官網檔案的推薦,為了保證生成一
${spring.application.name}:${spring.cloud.client.ipAddress}
- prefer-ip-address:開啟ip地址注冊
- ip-address:當前微服務的請求ip
啟動服務
記得修改server.port,instance-id(前者是埠號,后者是注冊的實體名字)
- 啟動效果
- 服務展示

- 實體展示

- 呼叫服務

- 發現之前eureka的配置(負載均衡,服務呼叫)可以繼續使用
八、Feign宣告式呼叫
服務呼叫Feign入門
前面我們使用的RestTemplate實作REST API呼叫,代碼大致如下:
@GetMapping("/ribbon/{id}")
public EasybuyProduct getOrderByRibbonId(@PathVariable long id){
return restTemplate.getForObject("http://ebuy-product/product/"+id,EasybuyProduct.class);
}
那么為什么RestTemplate用著好好的,為什么要用Feign呢?
由代碼可知,我們是使用拼接字串的方式構造URL的,該URL只有一個引數,
但是,在現實中,URL中往往含有多個引數,
這時候我們如果還用這種方式構造URL,那么就會非常痛苦,那應該如何解決? 我們帶著這樣的問題進入到本章的學習
Feign簡介
Feign是Netflix開發的宣告式,模板化的HTTP客戶端,其靈感來自Retrofit,JAXRS-2.0以及WebSocket.
- Feign可幫助我們更加便捷,優雅的呼叫HTTP API,
- 在SpringCloud中,使用Feign非常簡單——創建一個介面,并在介面上添加一些注解,代碼就完成了,
- Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等,
- SpringCloud對Feign進行了增強,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka,
從而讓Feign的使用更加方便,
基于Feign的服務呼叫
引入依賴
只需要在服務呼叫方添加即可!
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
啟動類添加Feign的支持

啟動類激活FeignClient
創建一個Feign介面,此介面是在Feign中呼叫微服務的核心介面
在服務消費者ebuy_order 添加一個 OrderFeginClient 介面

- 就是服務注冊方的controller方法
- 做個對比
之前的restTemplate負載均衡的呼叫

- 大體是相似的
修改呼叫controller

重啟服務
重啟服務,呼叫

- 測驗正常使用,并且負載均衡正常使用
Feign和Ribbon的聯系
Ribbon是一個基于 HTTP 和 TCP 客戶端 的負載均衡的工具,它可以 在客戶端
配置RibbonServerList(服務端串列),使用 HttpClient 或 RestTemplate
模擬http請求,步驟相當繁瑣,
Feign 是在 Ribbon的基礎上進行了一次改進,是一個使用起來更加方便的 HTTP 客戶端,采用介面的方式,只需要創建一個介面,然后在上面添加注解即可 ,將需要呼叫的其他服務的方法定義成抽象方 法即可,不需要自己構建http請求,然后就像是呼叫自身工程的方法呼叫,而感覺不到是呼叫遠程方法,使得撰寫客戶端變得非常容易,
負載均衡
Feign中本身已經集成了Ribbon依賴和自動配置,因此我們不需要額外引入依賴,也不需要再注冊
RestTemplate 物件,另外,我們可以像之前說的那樣去配置Ribbon,可以通過 ribbon.xx 來進
行全域配置,也可以通過 服務名.ribbon.xx 來對指定服務配置:

并且不依賴于之前的注解

- 仍然是負載均衡!!!
九、Feign的配置
為什么要配置Feign,之前用的不是好好的嗎?,要怎么配置?
因為真實的請求環境并不總是一帆風順,可能會網路阻塞、可能能會執行緒擁擠,導致feign呼叫的服務不能及時的完成服務的正常使用,導致報錯(接下來來個例子演示下)
- 修改服務提供者的controller

- 重啟服務
- 請求服務

報錯(讀取超時時間 超時)
- 配置方法一如下

代碼:
ebuy-product:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 隨機,默認輪詢
ConnectTimeout: 2500 # Ribbon的連接超時時間(創建連接時間:毫秒)
ReadTimeout: 5000 # Ribbon的資料讀取超時時間 (得到資料的時間)
OkToRetryOnAllOperations: true # 是否對所有操作都進行重試
MaxAutoRetriesNextServer: 1 # 切換實體的重試次數
MaxAutoRetries: 1 # 對當前實體的重試次數 (1表示不重試自己)
- 配置方法二 如下:
從Spring Cloud Edgware開始,Feign支持使用屬性自定義Feign,對于一個指定名稱的Feign Client(例如該Feign Client的名稱為 feignName ),Feign支持如下配置項:

代碼:
feign:
client:
config:
ebuy-product:
connectTimeout: 5000 # 相當于Request.Options
readTimeout: 5000 # 相當于Request.Options
# 配置Feign的日志級別,相當于代碼配置方式中的Logger
loggerLevel: full
-
connectTimeout : 建立鏈接的超時時長
-
readTimeout : 讀取超時時長
-
loggerLevel: Fegin的日志級別
-
errorDecoder :Feign的錯誤解碼器
-
retryer : 配置重試
-
requestInterceptors : 添加請求攔截器
-
decode404 : 配置熔斷不處理404例外
-
再次請求

-
雖然是慢了點,但是資料正常回傳,服務正常!!!
請求壓縮
Spring Cloud Feign 支持對請求和回應進行GZIP壓縮,以減少通信程序中的性能損耗,通過下面的引數即可開啟請求與回應的壓縮功能:
feign:
compression:
request:
enabled: true # 開啟請求壓縮
response:
enabled: true # 開啟回應壓縮
同時,我們也可以對請求的資料型別,以及觸發壓縮的大小下限進行設定:
feign:
compression:
request:
enabled: true # 開啟請求壓縮
mime-types: text/html,application/xml,application/json # 設定壓縮的資料型別
min-request-size: 2048 # 設定觸發壓縮的大小下限
注:上面的資料型別、壓縮大小下限均為默認值,
日志級別
在開發或者運行階段往往希望看到Feign請求程序的日志記錄,默認情況下Feign的日志是沒有開啟的,
要想用屬性配置方式來達到日志效果,只需在 application.yml 中添加如下內容即可:
feign:
client:
config:
order-product:
loggerLevel: FULL
logging:
level:
cn.warehouse.order.fegin.ProductFeginClient:
debug
- logging.level.xx : debug : Feign日志只會對日志級別為debug的做出回應
- feign.client.config.shop-service-product.loggerLevel : 配置Feign的日志Feign有四種
日志級別:- NONE【性能最佳,適用于生產】:不記錄任何日志(默認值)
- BASIC【適用于生產環境追蹤問題】:僅記錄請求方法、URL、回應狀態代碼以及執行時間
- HEADERS:記錄BASIC級別的基礎上,記錄請求和回應的header,
- FULL【比較適用于開發及測驗環境定位問題】:記錄請求和回應的header、body和元數
據,
十、Jmetter壓力測驗工具
Jmetter安裝十分簡單,下載解壓之后,安裝目錄下
bin/jmeter.bat 已管理員身份啟動即可


改造專案
改造order呼叫服務方的controller

上圖可以看出getMsg這個方法是不呼叫product模塊的服務的!
- 接下來修改tomcat的執行緒數

模擬洪峰環境(執行緒不足用戶使用)
- 然后重啟服務
配置測驗工具


啟動測驗


這顯然是不好的用戶體驗
十一、系統負載過高存在的問題
問題分析
在微服務架構中,我們將業務拆分成一個個的服務,服務與服務之間可以相互呼叫,由于網路原因或者自身的原因,服務并不能保證服務的100%可用,如果單個服務出現問題,呼叫這個服務就會出現網路延遲,此時若有大量的網路涌入,會形成任務累計,導致服務癱瘓,
在SpringBoot程式中,默認使用內置tomcat作為web服務器,單tomcat支持最大的并發請求是有限的,如果某一介面阻塞,待執行的任務積壓越來越多,那么勢必會影響其他介面的呼叫,
上述的測驗便是order呼叫product的服務出現問題,導致任務累計,進而使得order的tomcat的執行緒處于阻塞狀態,getMsg的請求被排隊,
那么如何解決上述的問題呢?
執行緒池的形式實作服務隔離
實作的主要思路是將上述的order呼叫product的服務的執行緒進行隔離,與getMsg方法不處在同一執行緒池中,進而使得getMsg方法正常執行,但是order呼叫product的服務仍然會很擁塞(但是可以回傳fallback,結束執行緒)!
引入jar包
<!--執行緒隔離-->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>1.5.12</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.12</version>
</dependency>
十二、服務熔斷斷Hystrix
服務容錯的核心知識
雪崩效應
在微服務架構中,一個請求需要呼叫多個服務是非常常見的,如客戶端訪問A服務,而A服務需要呼叫B
服務,B服務需要呼叫C服務,由于網路原因或者自身的原因,如果B服務或者C服務不能及時回應,A服
務將處于阻塞狀態,直到B服務C服務回應,此時若有大量的請求涌入,容器的執行緒資源會被消耗完畢,
導致服務癱瘓,服務與服務之間的依賴性,故障會傳播,造成連鎖反應,會對整個微服務系統造成災難 性的嚴重后果,這就是服務故障的“雪崩”效應,
雪崩是系統中的蝴蝶效應導致其發生的原因多種多樣,有不合理的容量設計,或者是高并發下某一個方
法回應變慢,亦或是某臺機器的資源耗盡,從源頭上我們無法完全杜絕雪崩源頭的發生,但是雪崩的根
本原因來源于服務之間的強依賴,所以我們可以提前評估,做好熔斷,隔離,限流,
服務隔離
顧名思義,它是指將系統按照一定的原則劃分為若干個服務模塊,各個模塊之間相對獨立,無強依賴,
當有故障發生時,能將問題和影響隔離在某個模塊內部,而不擴散風險,不波及其它模塊,不影響整體 的系統服務
熔斷降級
熔斷這一概念來源于電子工程中的斷路器(Circuit Breaker),在互聯網系統中,當下游服務因訪問壓
力過大而回應變慢或失敗,上游服務為了保護系統整體的可用性,可以暫時切斷對下游服務的呼叫,這 種犧牲區域,保全整體的措施就叫做熔斷
所謂降級,就是當某個服務熔斷之后,服務器將不再被呼叫,此時客戶端可以自己準備一個本地的
fallback回呼,回傳一個預設值, 也可以理解為兜底
服務限流
限流可以認為服務降級的一種,限流就是限制系統的輸入和輸出流量已達到保護系統的目的,一般來說
系統的吞吐量是可以被測算的,為了保證系統的穩固運行,一旦達到的需要限制的閾值,就需要限制流
量并采取少量措施以完成限制流量的目的,比方:推遲解決,拒絕解決,或者者部分拒絕解決等等,
Hystrix介紹
Hystrix是由Netflix開源的一個延遲和容錯庫,用于隔離訪問遠程系統、服務或者第三方庫,防止級聯失
敗,從而提升系統的可用性與容錯性,Hystrix主要通過以下幾點實作延遲和容錯,
- 包裹請求:使用HystrixCommand包裹對依賴的呼叫邏輯,每個命令在獨立執行緒中執行,這使用
了設計模式中的“命令模式”, - 跳閘機制:當某服務的錯誤率超過一定的閾值時,Hystrix可以自動或手動跳閘,停止請求該服務
一段時間, - 資源隔離:Hystrix為每個依賴都維護了一個小型的執行緒池(或者信號量),如果該執行緒池已滿,
發往該依賴的請求就被立即拒絕,而不是排隊等待,從而加速失敗判定, - 監控:Hystrix可以近乎實時地監控運行指標和配置的變化,例如成功、失敗、超時、以及被拒絕
的請求等, - 回退機制:當請求失敗、超時、被拒絕,或當斷路器打開時,執行回退邏輯,回退邏輯由開發人員
自行提供,例如回傳一個預設值, - 自我修復:斷路器打開一段時間后,會自動進入“半開”狀態,
restTemplate實作服務熔斷
引入jar包
<!--熔斷-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
因為要用到restTemplate的熔斷降級,記得將之前注釋掉的負載均衡注解去除
開啟熔斷
在啟動類 OrderApplication 中添加 @EnableCircuitBreaker 注解開啟對熔斷器的支持,
修改專案(區域熔斷處理)
解讀
由代碼可知,為 hystrixFindById 方法撰寫一個回退方法orderFallBack,該方法與 hystrixFindById 方法具有相同的引數與回傳值型別,該方法回傳一個默認的錯誤資訊, 在 hystrixFindById 方法上,使用注解
@HystrixCommand的fallbackMethod屬性,指定熔斷觸發的降級方法 是
orderFallBack, 因為熔斷的降級邏輯方法必須跟正常邏輯方法保證:相同的引數串列和回傳值宣告, 在
hystrixFindById 方法上 HystrixCommand(fallbackMethod = “orderFallBack”) 用來 宣告一個降級邏輯的方法 當ebuy-product 微服務正常時,瀏覽器訪問
http://localhost:9016/order/hystrix/816753
重啟專案
直接請求 測驗
這是因為之前在product服務提供方那里加了個執行緒休眠為2秒,而hystrix判斷服務超過1秒未回傳,就進行熔斷降級處理!!
修改組態檔
因為我們在product那里設定了休眠2秒,來模擬并發問題,
請求在超過1秒后都會回傳錯誤資訊,這是因為Hystix的默認超時時長為1,我們可以通過配置修改這個值:
再次請求
- 重啟專案,再次請求
- 未被熔斷降級處理,因為請求處理時長小于3秒
停止product提供者服務
當將商品微服務停止時繼續訪問
此時Hystrix配置已經生效進入熔斷降級方法,
全域熔斷處理
上述的熔斷處理已經實作,但是如果每一個請求都要配置一個對應的熔斷的兜底方法,那肯定是不行的!!!所以hystrix提供了一種全域的熔斷處理,
- 新建一個controller,與之前的controller作區分
package cn.ebuy.order.controller;
import cn.ebuy.order.pojo.EasybuyProduct;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/order2")
@DefaultProperties(defaultFallback = "orderFallBack")
public class Order2Controller {
@Autowired
RestTemplate restTemplate;
@GetMapping("/testString")
public String testString(){
return "測驗成功";
}
@RequestMapping(value = "/hystrix/{id}")
@HystrixCommand
public EasybuyProduct hystrixFindById(@PathVariable Long id){
EasybuyProduct easybuyProduct=restTemplate.getForObject("http://ebuy-product/product/"+id,EasybuyProduct.class);
return easybuyProduct;
}
/**
* 降級(兜底)
* @return
*/
/*注意全域的不要加引數*/
public EasybuyProduct orderFallBack(){
EasybuyProduct easybuyProduct=new EasybuyProduct();
easybuyProduct.setEpDescription("全域熔斷處理");
return easybuyProduct;
}
}
注意此時兜底的這個orderFallBack方法引數可以為空,但是回傳型別必須要和加了@HystrixCommand的方法保持一致,后期我們將寫一個包裝類(涵蓋物體泛型物件、以及一些基本資訊),用來作為熔斷降級的回傳型別,這里暫不做演示
重啟服務
重啟服務
服務正常提供
服務停止提供
熔斷降級處理
上述我們實作了restTemplate的熔斷降級,接下來實作Feign的熔斷降級!!!
Feign熔斷降級
引入jar包
SpringCloud Fegin默認已為Feign整合了hystrix,所以添加Feign依賴后就不用在添加hystrix,那么怎么才能讓Feign的熔斷機制生效呢,只要按以下步驟開發:
啟動類加注解
如果restTemplate的熔斷降級已經配置了的話,那么這一步省略
//開啟熔斷
@EnableCircuitBreaker
修改組態檔
feign:
hystrix: #在feign中開啟hystrix熔斷
enabled: true

新建一個Feign熔斷的類(組件)
package cn.ebuy.order.feign;
import cn.ebuy.order.pojo.EasybuyProduct;
import org.springframework.stereotype.Component;
//注意要加載該組件
@Component
public class OrderFeignClientCallBack implements OrderFeignClient {
@Override
public EasybuyProduct findById(Long id) {
EasybuyProduct easybuyProduct=new EasybuyProduct();
easybuyProduct.setEpDescription("Feign熔斷處理");
return easybuyProduct;
}
}

修改之前的Feign介面

重啟服務
product服務正常提供
停止product服務
這樣Feign的熔斷降級便是完成了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301019.html
標籤:其他
下一篇:想做測驗都需要哪些知識儲備呢?















