這篇文章,主要介紹微服務(wù)組件之Sentinel服務(wù)熔斷、服務(wù)降級、流量控制。
目錄
一、Sentinel組件
1.1、Sentinel介紹
1.2、Sentinel環(huán)境搭建
(1)引入依賴
(2)資源和規(guī)則
1.3、使用SphU定義資源
(1)定義資源
(2)定義規(guī)則
1.4、使用SphO定義資源
(1)定義資源
(2)定義規(guī)則
1.5、使用@SentinelResource注解定義資源
(1)定義資源
(2)定義規(guī)則
1.6、熔斷降級規(guī)則
(1)案例代碼
(2)五種降級規(guī)則
一、Sentinel組件
1.1、Sentinel介紹
Sentinel是Spring Cloud Alibaba提供的一個(gè)專門用于服務(wù)容錯(cuò)、服務(wù)熔斷、服務(wù)限流的微服務(wù)組件,它和hystrix組件的作用是類似的,但是Sentinel提供的功能比hystrix更加強(qiáng)大,Sentinel分為兩部分,一部分是Sentinel核心庫,另外一部分是Dashboard控制臺,Dashboard控制臺可以查看監(jiān)控的信息,接口的調(diào)用情況等。
有兩種使用Sentinel組件的方式,分別是:
- 第一種:引入Sentinel核心庫依賴,然后通過Java代碼的方式編寫流控規(guī)則。
- 第二種:通過Dashboard控制臺直接添加流控規(guī)則。
1.2、Sentinel環(huán)境搭建
Sentinel可以和很多的框架進(jìn)行整合,并且也可以單獨(dú)的使用,例如:和SpringCloud整合、和SpringBoot整合、Dubbo整合等,這里我就和SpringCloud進(jìn)行整合。
(1)引入依賴
<!-- 引入 web 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 sentinel 依賴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
引入sentinel依賴之后,基本的環(huán)境就搭建好了,接下來就是使用Sentinel進(jìn)行流量控制等代碼的編寫。
(2)資源和規(guī)則
在Sentinel中有兩種概念需要了解下,分別是:資源和規(guī)則。
資源就是指項(xiàng)目中的一個(gè)請求資源,可以將一段代碼、一個(gè)方法看作是資源,Sentinel就是以【資源】的形式進(jìn)行流控設(shè)置,定義資源之后,還需要給這個(gè)資源設(shè)置相對應(yīng)的流控規(guī)則,規(guī)則也就是說,這個(gè)資源什么情況下,需要發(fā)生熔斷、降級、限流等等操作呢,這些操作就是規(guī)則。
- 一般情況下,我們都使用方法名、URL、微服務(wù)名稱作為資源名稱來描述某個(gè)資源。
- 流量控制、熔斷降級、系統(tǒng)保護(hù)、來源訪問控制、熱點(diǎn)參數(shù)等等規(guī)則。
Sentinel提供了多種資源的定義方式,可以通過【@SentinelResource】注解定義資源,也可以通過Java代碼的方式手動的定義資源。下面分別介紹一下,幾種定義資源和規(guī)則的方式。
1.3、使用SphU定義資源
SphU是Sentinel提供的一個(gè)類,SphU是采用【try...catch】異常的方式來實(shí)現(xiàn)流控配置,當(dāng)發(fā)生流控的時(shí)候,就會拋出一個(gè)BlockException異常。
(1)定義資源
@GetMapping("/sphU")
public String demo01() {
Entry entry = null;
try {
// 1、開啟流控
entry = SphU.entry("sphU_demo01");
System.out.println("這里就是執(zhí)行具體業(yè)務(wù)邏輯");
} catch (BlockException e) {
e.printStackTrace();
// 記錄流控異常日志
Tracer.traceEntry(e, entry);
// 2、當(dāng)發(fā)生流控的時(shí)候,就會進(jìn)入這個(gè)異常塊里面
return "Sentinel發(fā)生流控,請稍后重試!";
} finally {
if (entry != null) {
// 3、退出流控
entry.exit();
}
}
return "接口調(diào)用成功";
}
(2)定義規(guī)則
/**
* 注入流控規(guī)則
*/
@PostConstruct
private void initFlowRule() {
List<FlowRule> ruleList = new ArrayList<>();
// 創(chuàng)建資源對應(yīng)的流控規(guī)則
FlowRule flowRule = new FlowRule();
// 設(shè)置當(dāng)前這個(gè)規(guī)則屬于哪個(gè)資源的
// 注意:不要用錯(cuò)方法,是調(diào)用【serResource()】方法,而不是【serRefResource()】,方法用錯(cuò)后,sentinel流控不生效
flowRule.setResource("sphU_demo01");
// 設(shè)置流控規(guī)則類型,這采用 QPS 方式
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 設(shè)置 QPS 的限制數(shù)量
flowRule.setCount(1);
ruleList.add(flowRule);
// 將流控規(guī)則添加到Sentinel里面
FlowRuleManager.loadRules(ruleList);
}
啟動工程,然后瀏覽器訪問【/api/sentinel/sphU】接口,連續(xù)多次刷新頁面,此時(shí)就會出現(xiàn)流控情況,從而拋出異常。
1.4、使用SphO定義資源
SphO也是Sentinel提供的一個(gè)類,它是采用【if...else】的方式來實(shí)現(xiàn)流控,當(dāng)觸發(fā)流控的時(shí)候,對應(yīng)方法會返一個(gè)boolean類型,false表示發(fā)生了流控,我們就可以根據(jù)方法的返回值,進(jìn)行代碼的處理。
(1)定義資源
@GetMapping("/sphO")
public String demo02() {
boolean entry = SphO.entry("sphO_demo02");
if (entry) {
try {
System.out.println("執(zhí)行具體業(yè)務(wù)邏輯...");
// 沒有發(fā)生流控,正常執(zhí)行業(yè)務(wù)邏輯代碼
return "接口調(diào)用成功";
} finally {
// 關(guān)閉流控
SphO.exit();
}
} else {
// 發(fā)生流控
return "Sentinel發(fā)生流控,請稍后重試!";
}
}
(2)定義規(guī)則
/**
* 注入流控規(guī)則
*/
@PostConstruct
public void initFlowRule() {
List<FlowRule> ruleList = new ArrayList<>();
// 創(chuàng)建資源對應(yīng)的流控規(guī)則
FlowRule flowRule = new FlowRule();
flowRule.setResource("sphO_demo02");
// 設(shè)置當(dāng)前這個(gè)規(guī)則屬于哪個(gè)資源的
// 設(shè)置流控規(guī)則類型,這采用 QPS 方式
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 設(shè)置 QPS 的限制數(shù)量
flowRule.setCount(1);
ruleList.add(flowRule);
// 將流控規(guī)則添加到Sentinel里面
FlowRuleManager.loadRules(ruleList);
}
1.5、使用@SentinelResource注解定義資源
@SentinelResource注解,用于定義資源,這個(gè)注解中有下面這些屬性:
- value:定義資源名稱。
- blockHandler:定義流控降級之后調(diào)用的方法。
- 方法必須定義在同一個(gè)類中。
- 方法必須是public的。
- 方法返回值必須和原方法的返回值一致。
- 方法參數(shù)必須相同,但是最后一個(gè)參數(shù)可以添加一個(gè)異常類參數(shù)。
- blockHandlerClass:作用和blockHandler一致,只是單獨(dú)寫到一個(gè)類里面了。
- fallback:當(dāng)對應(yīng)方法拋出異常時(shí)候,會調(diào)用這個(gè)降級方法。
(1)定義資源
package com.gitcode.demo.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @version 1.0.0
* @Date: 2023/4/25 17:07
* @Copyright (C) ZhuYouBin
* @Description:
*/
@RestController
@RequestMapping("/api/sentinel/demo")
public class SentinelDemo {
@SentinelResource(value = "sentinel_demo", blockHandler = "blockHandlerMethod", fallback = "fallbackMethod")
@GetMapping("/resource")
public String demo02() {
System.out.println("執(zhí)行具體業(yè)務(wù)邏輯...");
return "接口調(diào)用成功";
}
public String blockHandlerMethod() {
System.out.println("Sentinel發(fā)生流控,請稍后重試!");
return "Sentinel發(fā)生流控,請稍后重試!";
}
public String fallbackMethod(Throwable ex) {
System.out.println("Sentinel發(fā)生異常,請稍后重試!" + ex.getMessage());
return "Sentinel發(fā)生異常,請稍后重試!" + ex.getMessage();
}
}
(2)定義規(guī)則
/**
* 注入流控規(guī)則
*/
@PostConstruct
public void initFlowRule() {
List<FlowRule> ruleList = new ArrayList<>();
// 創(chuàng)建資源對應(yīng)的流控規(guī)則
FlowRule flowRule3 = new FlowRule();
// 設(shè)置當(dāng)前這個(gè)規(guī)則屬于哪個(gè)資源的
flowRule3.setResource("sentinel_demo");
// 設(shè)置流控規(guī)則類型,這采用 QPS 方式
flowRule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 設(shè)置 QPS 的限制數(shù)量
flowRule3.setCount(1);
ruleList.add(flowRule);
// 將流控規(guī)則添加到Sentinel里面
FlowRuleManager.loadRules(ruleList);
}
1.6、熔斷降級規(guī)則
通過Java代碼的方式設(shè)置降級規(guī)則,降級規(guī)則采用【DegradeRule】類表示,通過這個(gè)類設(shè)置一些規(guī)則,然后將其保存到【DegradeRuleManager】類中的緩存里面即可。
(1)案例代碼
/**
* 服務(wù)降級規(guī)則配置
*/
public void initDegradeRule() {
List<DegradeRule> degradeRuleList = new ArrayList<>();
// 設(shè)置降級規(guī)則
DegradeRule rule = new DegradeRule();
rule.setResource("資源名稱");
// 指定觸發(fā)降級的規(guī)則類型,有五種
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
// 設(shè)置發(fā)生異常時(shí)候數(shù)量
rule.setCount(2);
// 設(shè)置窗口時(shí)間
rule.setTimeWindow(10);
// 設(shè)置最小請求數(shù)量
rule.setMinRequestAmount(2);
degradeRuleList.add(rule);
// 加載到Sentinel里面
DegradeRuleManager.loadRules(degradeRuleList);
}
(2)五種降級規(guī)則
- DEGRADE_GRADE_EXCEPTION_COUNT:在指定時(shí)間內(nèi)發(fā)生的異常次數(shù)降級。
- DEGRADE_GRADE_EXCEPTION_RATIO:在指定時(shí)間內(nèi)發(fā)生的異常比率降級。
- DEGRADE_DEFAULT_MIN_REQUEST_AMOUNT:根據(jù)最小請求數(shù)量來實(shí)現(xiàn)降級。
- DEGRADE_GRADE_RT:根據(jù)響應(yīng)比進(jìn)行降級。
- DEGRADE_DEFAULT_SLOW_REQUEST_AMOUNT:最慢請求數(shù)量降級。
常用的就只有三個(gè),分別是:異常數(shù)量、異常比率、響應(yīng)比。文章來源:http://www.zghlxwxcb.cn/news/detail-854884.html
綜上,這篇文章結(jié)束了,主要介紹微服務(wù)組件之Sentinel服務(wù)熔斷、服務(wù)降級、流量控制。文章來源地址http://www.zghlxwxcb.cn/news/detail-854884.html
到了這里,關(guān)于【微服務(wù)筆記21】微服務(wù)組件之Sentinel服務(wù)熔斷、服務(wù)降級、流量控制介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!