文章目錄
- SpringCloud Alibaba
- 1、簡介
- 1.1 背景
- 1.2 Nacos主要功能
- 1.3 Nacos和SpringBoot、SpringCloud版本選擇
- 2、Nacos注冊中心
- 2.1 案例準備
- 2.2 Nacos注冊中心下載啟動
- 2.2.1 下載
- 2.2.2 解壓啟動
- 2.2.3 nacos-server訪問測試
- 2.3 nacos注冊中心客戶端整合
- 2.3.1 訂單服務整合nacos注冊中心
- 2.3.2 庫存服務整合nacos注冊中心
- 2.4 整合openFeign遠程調用
- 2.4.1 訂單服務整合openfeign
- 2.4.2 創建遠程調用Feign客戶端
- 2.4.3 添加@EnableFeignClients注解
- 2.4.4 遠程訪問實現
- 3、Nacos配置中心
- 3.1 簡介
- 3.2 nacos配置中心客戶端整合
- 3.3 配置中心配置加載
- 3.3.1 默認配置加載
- 1、創建配置
- 2、訂單服務加載配置
- 3.3.2 動態刷新配置
- 3.3.3 多環境配置文件加載
- 3.3.4 多配置文件加載
- 1、創建redis配置
- 2、訂單服務加載redis配置
- 3.3.5 配置分組
- 3.3.6 指定名稱空間加載配置
- 1、創建名稱空間
- 2、克隆配置到guli-online命名空間
- 3、訂單服務切換加載配置的命名空間
- 3.3.7 配置回滾
- 1、查看歷史版本
- 2、回滾
- 3.3 小結
- 4、Sentinel實現熔斷與限流
- 4.1 簡介
- 4.1.1 背景和作用
- 4.1.2 Sentinel與Hystrix的區別
- 4.2 Sentinel控制臺下載啟動
- 4.3 訂單服務整合Sentinel
- 4.3.1 引入依賴
- 4.3.2 配置
- 4.3.3 測試
- 4.4 Sentinel流量控制
- 4.4.1 簡介
- 4.4.2 基于QPS/并發數的流量控制
- 1、并發線程數流量控制
- 2、QPS流量控制
- 4.4.3 基于調用關系的流量控制
- 1、訂單服務創建新接口
- 2、創建關聯關系流控規則
- 4.5 Sentinel熔斷降級
- 4.5.1 調用下游服務熔斷降級
- 4.5.1.1 訂單服務application配置
- 4.5.1.2 編寫Feign客戶端的降級方案
- 4.5.1.3 Feign客戶端綁定降級方案
- 4.5.1.4 測試
- 4.5.2 不穩定資源的熔斷降級
- 4.5.2.1 平均響應時間
- 4.5.2.2 異常比例
- 4.5.2.3 異常數
- 4.6 熱點參數限流
- 4.6.1 訂單服務熱點key測試方法
- 4.6.2 sentinel控制臺添加熱點參數規則
- 4.6.3 測試
- 4.6.4 通過@SentinelResource返回兜底數據
- 4.6.5 熱點參數配置例外項
- 4.7 規則持久化
- 4.7.1 、nacos配置中心創建流控規則配置
- 4.7.2、訂單服務引入依賴
- 4.7.3、訂單服務application添加配置
- 4.7.4、測試
- 4.7.2、訂單服務引入依賴
- 4.7.3、訂單服務application添加配置
- 4.7.4、測試
SpringCloud Alibaba
1、簡介
1.1 背景
由于性能關系,Eureka停止更新,Hystrix和Ribbon進入維護模式,不再繼續更新。
2018.10.31,Spring Cloud Alibaba正式入駐了Spring Cloud官網孵化器,并在Maven中央庫發布了第一個版本。Spring Cloud Alibaba 致力于提供微服務開發的一站式解決方案。此項目包含開發分布式應用微服務的必需組件,方便開發者通過 Spring Cloud 編程模型輕松使用這些組件來開發分布式應用服務。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以將 Spring Cloud 應用接入阿里微服務解決方案,通過阿里中間件來迅速搭建分布式應用系統。
參考:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
常見的注冊中心:
Eureka(原生,2.0遇到性能瓶頸,停止維護)
Zookeeper(支持,專業的獨立產品。例如:dubbo)
Consul(原生,GO語言開發)
Nacos
相對于 Spring Cloud Eureka 來說,Nacos 更強大。
Nacos = Spring Cloud Eureka + Spring Cloud Config
Nacos 可以與 Spring, Spring Boot, Spring Cloud 集成,并能代替 Spring Cloud Eureka, Spring Cloud Config。
通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 實現配置的動態變更。
通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 實現服務的注冊與發現。
nacos在阿里巴巴內部有超過10萬的實例運行,已經過了類似雙十一等各種大型流量的考驗。
1.2 Nacos主要功能
Nacos主要提供以下四大功能:
-
服務發現和服務健康監測
-
動態配置服務
-
動態DNS服務
-
服務及其元數據管理
1.3 Nacos和SpringBoot、SpringCloud版本選擇
2、Nacos注冊中心
2.1 案例準備
拷貝課件中準備的案例到工作空間(兩個項目和之前eureka準備的項目一樣)
啟動測試:
2.2 Nacos注冊中心下載啟動
2.2.1 下載
下載地址:https://github.com/alibaba/nacos/releases
2.2.2 解壓啟動
解壓下載的nacos-server.zip后的目錄如下:
啟動nacos-server
? 注意!!!!!!:nacos運行的路徑中不能有中文,將解壓后的nacos剪切到無中文目錄下啟動
執行命令: startup.cmd -m standalone
2.2.3 nacos-server訪問測試
地址: http://localhost:8848/nacos
默認賬號/密碼:nacos/nacos
nacos-server集成了注冊中心和配置中心的功能
2.3 nacos注冊中心客戶端整合
2.3.1 訂單服務整合nacos注冊中心
guli-order-nacos服務pom中引入依賴:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.6.RELEASE</version>
</dependency>
application配置:
#spring:application:name: guli-order-nacoscloud:nacos:discovery:server-addr: localhost:8848
重啟guli-order-nacos:在控制臺可以看到注冊到nacos注冊中心的日志
nacos-server管理控制臺頁面中可以看到:
2.3.2 庫存服務整合nacos注冊中心
步驟參考訂單服務的整合…
整合成功后配置庫存服務多實例啟動
- 拷貝啟動配置
-
修改拷貝的啟動配置的端口號啟動
2.4 整合openFeign遠程調用
2.4.1 訂單服務整合openfeign
guli-order-nacos pom中引入依賴:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.6.RELEASE</version>
</dependency>
2.4.2 創建遠程調用Feign客戶端
guli-order-nacos中創建Feign客戶端
@FeignClient("guli-stock-nacos")
public interface GuliStockNacosClient {@GetMapping("/stock/{productId}/{count}")public Boolean updateStock(@PathVariable("productId")String productId ,@PathVariable("count") Integer count);}
2.4.3 添加@EnableFeignClients注解
@SpringBootApplication
@EnableFeignClients
public class GuliOrderNacosApplication {public static void main(String[] args) {SpringApplication.run(GuliOrderNacosApplication.class,args);}
}
2.4.4 遠程訪問實現
guli-order-nacos中通過GuliStockNacosClient遠程更新庫存
@Autowired
GuliStockNacosClient guliStockNacosClient;
//創建訂單
public boolean saveOrder(String userId,String productId,Integer count){//.......Boolean stock = guliStockNacosClient.updateStock(productId, count);System.out.println("更新庫存:"+stock);return orderEntity!=null;
}
feign默認使用ribbon負載均衡模塊輪詢的策略進行遠程調用。
3、Nacos配置中心
3.1 簡介
在系統開發過程中,開發者通常會將一些需要變更的參數、變量等從代碼中分離出來獨立管理,以獨立的配置文件的形式存在。目的是讓靜態的系統工件或者交付物(如 WAR,JAR 包等)更好地和實際的物理運行環境進行適配。配置管理一般包含在系統部署的過程中,由系統管理員或者運維人員完成。配置變更是調整系統運行時的行為的有效手段。
如果微服務架構中沒有使用統一配置中心時,所存在的問題:
-
配置文件分散在各個項目里,不方便維護
-
配置內容安全與權限
-
更新配置后,項目需要重啟
nacos配置中心:系統配置的集中管理(編輯、存儲、分發)、動態更新不重啟、回滾配置(變更管理、歷史版本管理、變更審計)等所有與配置相關的活動。
3.2 nacos配置中心客戶端整合
guli-order-nacos服務引入依賴:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2.2.6.RELEASE</version>
</dependency>
application中添加配置:
#spring:
# cloud:
# nacos:
# discovery:
# server-addr: localhost:8848config: # 配置中心地址server-addr: localhost:8848
重啟guli-order-nacos服務可以看到控制臺日志:配置中心默認加載的配置文件
3.3 配置中心配置加載
3.3.1 默認配置加載
1、創建配置
參考項目啟動時的日志要加載的默認配置信息,我們可以在nacos配置中心默認分組中創建guli-order-nacos或者guli-order-nacos.properties配置文件 并提供配置。
2、訂單服務加載配置
guli-order-nacos 獲取配置中心配置:
@Value("${order.app.name}")
String appName;
@GetMapping("{userId}/{productId}/{count}")
public Boolean createOrder(@PathVariable("userId")String userId,@PathVariable("productId")String productId,@PathVariable("count")Integer count){System.out.println("配置中心參數appName :" + appName);return orderService.saveOrder(userId,productId,count);
}
訪問接口測試:加載成功
3.3.2 動態刷新配置
修改配置中心配置信息:將order.app.name值改為guli-order-naocs2,并發布配置
如果不重啟訂單服務,不能加載最新的配置。
在使用配置中心配置的類名上添加注解:@RefreshScope
@RefreshScope
public class OrderController{ ... }
重新測試配置的動態加載…
3.3.3 多環境配置文件加載
nacos配置中心加載默認配置時還會使用開發中不同的環境去加載
訂單服務application中添加環境配置:
#spring:profiles:active: dev
重啟訂單服務,可以看到默認加載的配置文件如下:
參考3.3.2 在配置中心創建guli-order-nacos-dev.properties 編寫配置測試加載。
3.3.4 多配置文件加載
除了默認的配置外,也可以自定義要加載的文件名。
1、創建redis配置
2、訂單服務加載redis配置
不是默認的配置文件,需要創建bootstrap.yml/properties文件,編寫要加載的配置文件信息
spring:cloud:nacos:config:server-addr: localhost:8848extension-configs:# 指定加載的一個配置中心配置信息- dataId: redis.properties # dataIdgroup: DEFAULT_GROUP # 組名refresh: true # 是否監聽配置改變
使用配置:
@RestController
@RefreshScope
@RequestMapping("/order")
public class OrderController {@AutowiredOrderService orderService;@Value("${order.app.name}")String appName;@Value("${redis.host}")String redisHost;@Value("${redis.port}")Integer redisPort;@GetMapping("{userId}/{productId}/{count}")public Boolean createOrder(@PathVariable("userId")String userId,@PathVariable("productId")String productId,@PathVariable("count")Integer count){System.out.println("配置中心參數appName :" + appName);System.out.println("配置中心redis參數:host = "+ redisHost+" , port = "+ redisPort);return orderService.saveOrder(userId,productId,count);}
}
3.3.5 配置分組
在實際開發中,除了不同的環境外。不同的微服務或者業務功能,可能有不同的redis及mysql數據庫。區分不同的環境我們使用名稱空間(namespace),區分不同的微服務或功能,使用分組(group)。
當然,你也可以反過來使用,名稱空間和分組只是為了更好的區分配置,提供的兩個維度而已。
新增一個redis.properties,所屬分組為ORDER_GROUP
訂單服務bootstrap配置中指定加載的redis配置分組:
spring:cloud:nacos:config:server-addr: localhost:8848extension-configs:# 指定加載的一個配置中心配置信息- dataId: redis.properties # dataIdgroup: ORDER_GROUP # 組名refresh: true # 是否監聽配置改變
3.3.6 指定名稱空間加載配置
在實際開發中,通常有多套不同的環境(默認只有public),那么這個時候可以根據指定的環境來創建不同的 namespce,例如,開發、測試和生產三個不同的環境,那么使用一套 nacos 集群可以分別建以下三個不同的 namespace。以此來實現多環境的隔離。
1、創建名稱空間
2、克隆配置到guli-online命名空間
查看克隆以后的guli-online配置中心配置列表:
3、訂單服務切換加載配置的命名空間
在訂單服務的bootstrap.yml中添加配置:spring.cloud.nacos.config.namespace并指定值為要加載配置的命名空間id
spring:cloud:nacos:config:server-addr: localhost:8848namespace: edbae1c7-5ceb-4f29-bd5c-70d9368ef1ff # guli-online命名空間IDextension-configs:# 指定加載的一個配置中心配置信息- dataId: redis.properties # dataIdgroup: ORDER_GROUP # 組名refresh: true # 是否監聽配置改變
修改配置重啟測試是否加載成功。
3.3.7 配置回滾
nacos還會保存配置修改的歷史記錄以防止誤操作之后的回滾。
1、查看歷史版本
2、回滾
點擊詳情可以查看配置信息,點擊回滾確認后可以回滾成功。
測試,略…
3.3 小結
配置中心將配置從各個應用中剝離出來,自成一體,對所有的配置進行單獨的統一管理,優雅的解決了日志管理的諸多問題。在系統架構中,和安全、日志、監控等非功能需求一樣,配置管理也是一種非功能需求。配置中心是整個微服務基礎架構體系中的一個組件。總得來說,配置中心就是一種統一管理各種應用配置的基礎服務組件。
4、Sentinel實現熔斷與限流
4.1 簡介
4.1.1 背景和作用
官網:https://sentinelguard.io/zh-cn/docs/introduction.html
隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。在大規模微服務架構的場景下,避免服務出現雪崩,要減少停機時間,要盡可能的提高服務可用性。限流和降級是一個非常重要的手段,具體實施方法可以歸納為八字箴言,分別是限流,降級,熔斷和隔離。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
Sentinel 具有以下特征:
· 豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應用等。
· 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制臺中看到接入應用的單臺機器秒級數據,甚至 500 臺以下規模的集群的匯總運行情況。
· 廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
· 完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展接口。您可以通過實現擴展接口來快速地定制邏輯。例如定制規則管理、適配動態數據源等。
Sentinel 目前已經針對 Servlet、Dubbo、Spring Boot/Spring Cloud、gRPC 等進行了適配,用戶只需引入相應依賴并進行簡單配置即可非常方便地享受 Sentinel 的高可用流量防護能力。
4.1.2 Sentinel與Hystrix的區別
Hystrix常用的線程池隔離會造成線程上下切換的overhead比較大;
Hystrix使用的信號量隔離對某個資源調用的并發數進行控制,效果不錯,但是無法對慢調用進行自動降級;
Sentinel通過并發線程數的流量控制提供信號量隔離的功能;
Sentinel支持的熔斷降級維度更多,可對多種指標進行流控、熔斷,且提供了實時監控和控制面板,功能更為強大。
Sentinel | Hystrix | |
---|---|---|
隔離策略 | 信號量隔離 | 線程池隔離/信號量隔離 |
熔斷降級策略 | 基于響應時間或失敗比率 | 基于失敗比率 |
實時指標實現 | 滑動窗口 | 滑動窗口(基于 RxJava) |
規則配置 | 支持多種數據源 | 支持多種數據源 |
擴展性 | 多個擴展點 | 插件的形式 |
基于注解的支持 | 支持 | 支持 |
限流 | 基于 QPS,支持基于調用關系的限流 | 不支持 |
流量整形 | 支持慢啟動、勻速器模式 | 不支持 |
系統負載保護 | 支持 | 不支持 |
控制臺 | 開箱即用,可配置規則、查看秒級監控、機器發現等 | 不完善 |
常見框架的適配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Netflix |
4.2 Sentinel控制臺下載啟動
下載地址:https://github.com/alibaba/Sentinel/releases
啟動:
打開sentinel所在目錄的dos命令窗口
啟動sentinel控制臺: java -jar sentinel-dashboard-1.8.2.jar
訪問控制臺:localhost:8080
默認賬號/密碼: sentinel
4.3 訂單服務整合Sentinel
4.3.1 引入依賴
guli-order-nacos服務pom中引入依賴
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2.2.3.RELEASE</version>
</dependency>
4.3.2 配置
guli-order-nacos application中添加sentinel配置
#spring:
# cloud:sentinel:transport:port: 8719 # 數據傳輸端口號dashboard: localhost:8080 # sentinel控制臺地址eager: true # 主動注冊到sentinel控制臺filter:url-patterns: /** # sentinel過濾的地址
4.3.3 測試
重啟訂單服務查看sentinel控制臺,可以查看到成功注冊的sentinel客戶端
4.4 Sentinel流量控制
4.4.1 簡介
Sentinel 支持以下幾種規則:流量控制規則、熔斷降級規則、系統保護規則、來源訪問控制規則 和 熱點參數規則。其中流量控制規則可以基于QPS/并發數或者基于調用關系對一個服務的流量進行控制
流量控制規則 (FlowRule),重要屬性:
Field | 說明 | 默認值 |
---|---|---|
resource | 資源名,資源名是限流規則的作用對象 | |
count | 限流閾值 | |
grade | 限流閾值類型,QPS 或線程數模式 | QPS 模式 |
limitApp | 流控針對的調用來源 | default ,代表不區分調用來源 |
strategy | 調用關系限流策略:直接、鏈路、關聯 | 根據資源本身(直接) |
controlBehavior | 流控效果(直接拒絕 / 排隊等待 / 慢啟動模式),不支持按調用關系限流 | 直接拒絕 |
同一個資源可以同時有多個限流規則。
注意:流控規則默認保存在服務的運行內存中,重啟服務流控規則需要重新配置
4.4.2 基于QPS/并發數的流量控制
流量控制主要有兩種統計類型,一種是統計線程數,另外一種則是統計 QPS。
1、并發線程數流量控制
線程數限流用于保護業務線程數不被耗盡。例如,當應用所依賴的下游應用由于某種原因導致服務不穩定、響應延遲增加。這種隔離方案雖然能夠控制線程數量,但無法控制請求排隊時間,直接拒絕能夠迅速降低系統壓力。Sentinel線程數限流不負責創建和管理線程池,而是簡單統計當前請求上下文的線程個數,如果超出閾值,新的請求會被立即拒絕。
在sentinel控制臺新增流控規則:
使用jmeter創建線程組并發訪問創建訂單接口。
瀏覽器同時直接訪問創建訂單接口,會出現限流后直接失敗的頁面:
在sentinel控制臺實時監控也可以看到并發的請求被拒絕的數量(拒絕QPS)
2、QPS流量控制
當 QPS 超過某個閾值的時候,則采取措施進行流量控制。流量控制的手段包括下面 3 種,對應 FlowRule
中的 controlBehavior
字段:
-
直接拒絕方式。該方式是默認的流量控制方式,當QPS超過任意規則的閾值后,新的請求就會被立即拒絕。
刪除之前的流控規則,創建QPS流控規則,流控效果為快速失敗
? 測試:以上配置手速較快的同學可以在瀏覽器快速刷新訪問一秒鐘超過3次請求則會進入流控頁面。無需借助Jmeter測試
-
冷啟動方式。該方式主要用于系統長期處于低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮的情況。
刪除之前的流控規則,創建QPS流控規則,流控效果為WarmUp
? 默認低水位QPS為 QPS閾值/冷加載因子(3) ,經過預熱時長后才達到閾值,上面的配置低水位為 10/3也就是默認QPS為3,請求較多時,QPS4秒后會達到10
? 測試:手速快的同學又可以表現了,在瀏覽器地址欄訪問創建訂單接口,瘋狂刷新訪問,第一秒第四次請求會返回失敗頁面,到第四秒以后,基本不會出現失敗頁面。
? jmeter并發測試,等到穩定時,QPS基本在10左右
-
勻速器方式。這種方式嚴格控制了請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶算法。
訂單服務創建訂單接口中輸出時間毫秒數重啟,然后創建勻速器流控規則
以上規則:每秒可以通過3個請求,超過的請求排隊等待,等待超過2000毫秒則超時返回失敗頁面
測試:使用jmeter或者手動測試。
4.4.3 基于調用關系的流量控制
當關聯的資源達到閾值時,就限流自己。例如A關聯B,訪問B達到閾值后,就限流A。
應用場景:兩個接口使用共享資源時,進行流量限制
1、訂單服務創建新接口
關聯的兩個資源不需要有依賴或者調用關系
@GetMapping("/test")
public String test(){return "test";
}
重啟訂單服務
2、創建關聯關系流控規則
以上配置,如果訪問/order/test資源的QPS超過3個,則對/order/{userId}/{productId}/{count}資源的訪問進行限流,快速返回失敗頁面。
測試:
- 先在jmeter中通過線程組并發訪問/order/test接口
- 在瀏覽器中訪問創建訂單接口:http://localhost:18081/order/9527/1001/1 出現限流頁面代表限流成功
4.5 Sentinel熔斷降級
除了流量控制以外,對調用鏈路中不穩定的資源進行熔斷降級也是保障高可用的重要措施之一。一個服務常常會調用別的模塊,可能是另外的一個遠程服務、數據庫,或者第三方 API 等。例如,支付的時候,可能需要遠程調用銀聯提供的 API;查詢某個商品的價格,可能需要進行數據庫查詢。然而,這個被依賴服務的穩定性是不能保證的。如果依賴的服務出現了不穩定的情況,請求的響應時間變長,那么調用服務的方法的響應時間也會變長,線程會產生堆積,最終可能耗盡業務自身的線程池,服務本身也變得不可用。
4.5.1 調用下游服務熔斷降級
4.5.1.1 訂單服務application配置
feign:sentinel: # 啟用sentinel對feign客戶端的代理enabled: true
4.5.1.2 編寫Feign客戶端的降級方案
@Component
public class GuliStockNacosClientFallback implements GuliStockNacosClient{@Overridepublic Boolean updateStock(String productId, Integer count) {System.out.println("遠程訪問失敗,使用降級方案處理.");return false;}
}
4.5.1.3 Feign客戶端綁定降級方案
@FeignClient(value = "guli-stock-nacos" , fallback = GuliStockNacosClientFallback.class)
public interface GuliStockNacosClient {@GetMapping("/stock/{productId}/{count}")public Boolean updateStock(@PathVariable("productId")String productId ,@PathVariable("count") Integer count);}
4.5.1.4 測試
關閉庫存服務,重啟訂單服務,訪問訂單服務創建訂單接口測試:http://localhost:18081/order/9527/1001/1
啟動庫存服務,訪問創建訂單接口時,不會使用降級方案處理。
4.5.2 不穩定資源的熔斷降級
Sentinel 提供以下幾種熔斷策略:
RT(平均響應時間,秒級)
? 平均響應時間 (DEGRADE_GRADE_RT):超過閾值 且時間窗口內的請求>=5,兩個條件同時滿足后觸發降級,窗口期過后關閉斷路器
? RT 最大4900 ms,更大的需要通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
異常比例(秒級)
? QPS>=5且異常比例(秒級統計)超過閾值時,觸發降級;時間窗口結束后,關閉降級
異常數(分鐘級)
? 異常數(分鐘統計)超過閾值時,觸發降級;時間窗口結束后,關閉降級
Sentinel熔斷降級會在調用鏈路中某個資源出現不穩定狀態時(例如:調用超時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其他的資源而導致級聯錯誤。
當資源被降級后,在接下來的降級時間窗口之內,對該資源的調用都自動熔斷(默認行為是拋出DegradeException)。
Sentinel的斷路器是沒有半開狀態的,沒有異常就關閉斷路器恢復使用,有異常則繼續打開斷路器不可用。(對比Hystrix)
4.5.2.1 平均響應時間
在訂單服務的test接口中添加休眠代碼,并重啟訂單服務。
@GetMapping("/test")
public String test(){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return "test";
}
sentinel控制臺添加平均響應時間流控規則
? 以上規則表示:訪問/order/test資源,統計時長1秒內超過3個請求時,統計他們的平均響應時間,如果比例達到50%,則熔斷3秒,時間窗口內所有請求都會返回默認流控頁面。
? 測試:
> 直接訪問/order/test 是可以訪問的。>> 使用jmeter并發訪問/order/test,此時瀏覽器訪問/order/test會直接返回失敗,因為進入熔斷狀態了。
4.5.2.2 異常比例
訂單服務修改test接口并重啟:
@GetMapping("/test")
public String test(){int a = 1/0;return "test";
}
sentinel控制臺創建異常比例熔斷規則:
以上規則表示:在2秒內請求達到三個時,如果異常比例超過一半,熔斷3秒鐘,此時新的請求直接返回默認降級頁面。
測試:瀏覽器中直接訪問http://localhost:18081/order/test 連續訪問測試
4.5.2.3 異常數
刪除之前的熔斷規則
創建異常數熔斷規則
以上規則表示:2秒內達到五個請求時,如果異常數>=5個,熔斷5秒(注意:1.8以前版本的sentinel,熔斷時長必須超過60秒)
測試:訪問訂單服務 http://localhost:18081/order/test,觀察慢慢訪問和快速連續訪問的區別。
4.6 熱點參數限流
何為熱點?熱點即經常訪問的數據。很多時候我們希望統計某個熱點數據中訪問頻次最高的 Top K 數據,并對其訪問進行限制。比如:
- 商品 ID 為參數,統計一段時間內最常購買的商品 ID 并進行限制
- 用戶 ID 為參數,針對一段時間內頻繁訪問的用戶 ID 進行限制
熱點參數限流會統計傳入參數中的熱點參數,并根據配置的限流閾值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。
Sentinel 利用 LRU 策略統計最近最常訪問的熱點參數,結合令牌桶算法來進行參數級別的流控。
4.6.1 訂單服務熱點key測試方法
修改訂單服務/order/test資源,接收兩個參數pid和count,并且使用@SentinelResource注解指定資源名(熱點參數必須通過注解配置的資源名來處理)
@GetMapping("/test")
@SentinelResource(value = "testResource")
public String test(@RequestParam(value = "pid",required = false)String pid,@RequestParam(value = "count",required = false)String count){System.out.println("購買商品的id為:"+pid+" , 數量:"+count);return "test";
}
重啟訂單服務
4.6.2 sentinel控制臺添加熱點參數規則
以上規則表示:攜帶第一個參數時(參數索引為0)訪問資源testResource時,1秒內QPS超過3個的請求會拋出ParamFlowException,由于代碼中每處理所以返回500頁面。
4.6.3 測試
測試:瀏覽器連續快速訪問 http://localhost:18081/order/test?pid=1
控制臺可以看到以下異常。
如果訪問:http://localhost:18081/order/test?count=1 則沒有異常
4.6.4 通過@SentinelResource返回兜底數據
@SentinelResource注解:
? blockHandlerClass:兜底方法所在類
? blockHandler:指定兜底方法,因為是使用類名.方法名調用的,所以必須是靜態方法。必須接收異常處理
@GetMapping("/test")
@SentinelResource(value = "testResource",blockHandler = "deadTest" , blockHandlerClass = OrderController.class)
public String test(@RequestParam(value = "pid",required = false)String pid,@RequestParam(value = "count",required = false)String count){System.out.println("購買商品的id為:"+pid+" , 數量:"+count);return "test";
}
//也可以將熔斷降級的自定義方法抽取到單獨的一個類中,此處省略....
public static String deadTest(String pid, String count, BlockException blockException){System.out.println("deadTest---購買商品的id為:"+pid+" , 數量:"+count+" , 異常: "+ blockException);return "dead_test";
}
?
重啟服務
按照4.6.2重新配置熱點參數規則
測試:瀏覽器連續快速訪問 http://localhost:18081/order/test?pid=1
? idea控制臺:
? 瀏覽器接收到的兜底數據
4.6.5 熱點參數配置例外項
sentinel控制臺修改之前的熱點規則: 按照下圖添加參數例外項(一定要點添加)
瀏覽器快速連續訪問測試:
? http://localhost:18081/order/test?pid=1
? http://localhost:18081/order/test?pid=2
? 觀察結果:
4.7 規則持久化
上述 方法只接受內存態的規則對象,但更多時候規則存儲在文件、數據庫或者配置中心當中。DataSource
接口給我們提供了對接任意配置源的能力。相比直接通過 API 修改規則,實現 DataSource
接口是更加可靠的做法。
我們推薦通過控制臺設置規則后將規則推送到統一的規則中心,客戶端實現 ReadableDataSource
接口端監聽規則中心實時獲取變更,流程如下:
4.7.1 、nacos配置中心創建流控規則配置
? 配置字段說明:
[{"resource": "/retaLimit/byUrl","limitApp": "default","grade": 1,"count": 1,"strategy": 0,"controlBehavior": 0,"clusterMode": false }
]
4.7.2、訂單服務引入依賴
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId><version>1.8.1</version>
</dependency>
4.7.3、訂單服務application添加配置
sentinel從nacos注冊中心加載持久化規則的配置
#spring:
# cloud:sentinel:datasource:ds1:nacos:server-addr: localhost:8848dataId: cloudalibaba-sentinel-servicenamespace: edbae1c7-5ceb-4f29-bd5c-70d9368ef1ffgroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow
4.7.4、測試
外鏈圖片轉存中…(img-Lp0CrByD-1715585522459)]
[外鏈圖片轉存中…(img-6tvHfMnE-1715585522460)]
[外鏈圖片轉存中…(img-sW2z1Rog-1715585522460)]
[{"resource": "/retaLimit/byUrl","limitApp": "default","grade": 1,"count": 1,"strategy": 0,"controlBehavior": 0,"clusterMode": false }
]
4.7.2、訂單服務引入依賴
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId><version>1.8.1</version>
</dependency>
4.7.3、訂單服務application添加配置
sentinel從nacos注冊中心加載持久化規則的配置
#spring:
# cloud:sentinel:datasource:ds1:nacos:server-addr: localhost:8848dataId: cloudalibaba-sentinel-servicenamespace: edbae1c7-5ceb-4f29-bd5c-70d9368ef1ffgroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow
4.7.4、測試
重啟訂單服務,刷新sentinel控制臺可以看到持久化的流控規則