Sentinel在订单大量服务调用的应用场景
Sentinel譯為“哨兵”,顧名思義,面對您后臺的大量服務/微服務,前置一個哨兵,但面對大量請求時,讓后臺服務有序被調用,但某些服務的不可用時,采用服務熔斷降級等措施,讓系統仍能平穩運行,不至于造成系統雪崩,典型應用場景:
image
隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
Sentinel 具有以下特征:
-
豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍)、消息削峰填谷、實時熔斷下游不可用應用等。
-
完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制臺中看到接入應用的單臺機器秒級數據,甚至 500 臺以下規模的集群的匯總運行情況。
-
廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
-
完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展點。您可以通過實現擴展點,快速的定制邏輯。例如定制規則管理、適配數據源等。
Sentinel分為兩部分:
核心庫(Java 客戶端)不依賴任何框架/庫,能夠運行于所有 Java 運行時環境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。
控制臺(Dashboard)基于 Spring Boot 開發,打包后可以直接運行,不需要額外的 Tomcat 等應用容器,該模塊目前基于SpringBoot運行;
部署
在使用Sentinel之前,我們首先需部署Sentinel Dashborad,下載最新版的Sentinel Dashborad,通過以下命令運行:
?
java -Dserver.port=8088 -jar sentinel-dashboard-1.3.0.jar通過server.port執行程序運行端口號,通過http://localhost:8088打開控制臺,如下:
image
至此部署完成,非常簡單!
項目中使用Sentinel
Sentinel針對各個主流框架都提供了適配(包括Servlet,Dubbo,SpringBoot/SpringCloud,gRPC,RocketMQ等),本文以SpringBoot2舉例(通過筆者測試發現,SpringBoot 1.x支持不好,自定義流控規則不可用),首先我們需要在SpringBoot2的配置文件中指定Sentinel連接的控制臺地址和項目名,即application.yml文件,如下:
?
project:name: 在控制臺顯示的項目名 spring:cloud:sentinel:transport:dashboard: 192.168.1.154:8088在項目中加入依賴:
?
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>0.2.0.RELEASE</version> </dependency>啟動SpringBoot2后,可以在簇點鏈路頁面看到項目的各個服務(首次訪問服務時會被出現在列表中,這些服務在Sentinel中被稱為資源),接著,你就可以針對這些資源進行流控,降級,熱點,授權等操作。
流量控制與規則擴展
在控制臺可通過流控規則菜單定義某資源的流控規則,不過這個定義只在內存中,但控制臺重啟后,隨之消失,所以我們一般在項目中通過配置文件來定義流控規則,編寫一個流控數據源,如下:
?
package com.sumscope.study.springboot2.service;import java.net.URLDecoder; import java.util.List;import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.init.InitFunc; import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource; import com.alibaba.csp.sentinel.property.PropertyListener; import com.alibaba.csp.sentinel.property.SentinelProperty; import com.alibaba.csp.sentinel.slots.block.Rule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.slots.system.SystemRule; import com.alibaba.csp.sentinel.slots.system.SystemRuleManager; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; public class FileDataSourceInit implements InitFunc{private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(source,new TypeReference<List<FlowRule>>() {});private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(source,new TypeReference<List<DegradeRule>>() {});private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(source,new TypeReference<List<SystemRule>>() {});@Overridepublic void init() throws Exception {ClassLoader classLoader = getClass().getClassLoader();String flowRulePath = URLDecoder.decode(classLoader.getResource("FlowRule.json").getFile(), "UTF-8");String degradeRulePath = URLDecoder.decode(classLoader.getResource("DegradeRule.json").getFile(), "UTF-8");String systemRulePath = URLDecoder.decode(classLoader.getResource("SystemRule.json").getFile(), "UTF-8");// Data source for FlowRuleFileRefreshableDataSource<List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(flowRulePath, flowRuleListParser);FlowRuleManager.register2Property(flowRuleDataSource.getProperty());// Data source for DegradeRuleFileRefreshableDataSource<List<DegradeRule>> degradeRuleDataSource= new FileRefreshableDataSource<>(degradeRulePath, degradeRuleListParser);DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());// Data source for SystemRuleFileRefreshableDataSource<List<SystemRule>> systemRuleDataSource= new FileRefreshableDataSource<>(systemRulePath, systemRuleListParser);SystemRuleManager.register2Property(systemRuleDataSource.getProperty());} }然后在項目的resources下新增目錄META-INF\services\com.alibaba.csp.sentinel.init.InitFunc,并填寫以上類的完成類名如com.sumscope.study.springboot2.service.FileDataSourceInit即可,這樣,在您的classpath目錄下通過DegradeRule.json,FlowRule.json,SystemRule.json分別來定義降級規則,流控規則和系統規則,比如我們定義一個流控規則,讓test資源QPS為1,即1秒鐘最多調用1次,如下:
?
[{"resource": "test","controlBehavior": 0,"count": 1,"grade": 1,"limitApp": "default","strategy": 0} ]在Java代碼中,通過@SentinelResource("test")來定義服務對應的資源名,如果不指數,URI即為資源名。
熔斷降級
降級規則定義如下:
image
可基于RT(平均響應時間)或異常比例兩種方式來定義,其中RT單位為毫秒。
指定RT時,當資源的平均響應時間超過閾值(DegradeRule 中的 count,以 ms 為單位)之后,資源進入準降級狀態。接下來如果持續進入 5 個請求,它們的 RT 都持續超過這個閾值,那么在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的調用都會自動地返回。
指定異常時,當資源的每秒異常總數占通過總數的比值超過閾值(DegradeRule 中的 count)之后,資源進入降級狀態,即在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的調用都會自動地返回。
熱點參數限流
也可對經常訪問的數據進行限流,如某個商品或某個用戶等,如下圖:
image
Sentinel 利用 LRU 策略,結合底層的滑動窗口機制來實現熱點參數統計。LRU 策略可以統計單位時間內,最近最常訪問的熱點參數,而滑動窗口機制可以幫助統計每個參數的 QPS,熱點參數限流目前只支持QPS模式。
黑白名單
可通過定義策略(黑名單或白名單)限定資源的調用方是否讓其通過,以下是代碼定義白名單規則:
?
AuthorityRule rule = new AuthorityRule(); rule.setResource("test"); rule.setStrategy(RuleConstant.AUTHORITY_WHITE); rule.setLimitApp("appA,appB"); AuthorityRuleManager.loadRules(Collections.singletonList(rule));實時監控
在控制臺我們可以實時看到每個資源的qps情況如下圖:
image
注:其中p_qps是每秒通過的請求數,b_qps是每秒拒絕的請求數
?
總結
以上是生活随笔為你收集整理的Sentinel在订单大量服务调用的应用场景的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么选用NACOS
- 下一篇: MOSS 代替Spring Boot A