系列文章目錄
第一章 Java線程池技術(shù)應(yīng)用
第二章 CountDownLatch和Semaphone的應(yīng)用
第三章 Spring Cloud 簡介
第四章 Spring Cloud Netflix 之 Eureka
第五章 Spring Cloud Netflix 之 Ribbon
第六章 Spring Cloud 之 OpenFeign
第七章 Spring Cloud 之 GateWay
第八章 Spring Cloud Netflix 之 Hystrix
第九章 代碼管理gitlab 使用
第十章 SpringCloud Alibaba 之 Nacos discovery
第十一章 SpringCloud Alibaba 之 Nacos Config
第十二章 Spring Cloud Alibaba 之 Sentinel
前言
Sentinel 是由阿里巴巴中間件團隊開發(fā)的開源項目,是一種面向分布式微服務(wù)架構(gòu)的輕量級高可用流量控制組件。
Sentinel 主要以流量為切入點,從流量控制、熔斷降級、系統(tǒng)負載保護等多個維度幫助用戶保護服務(wù)的穩(wěn)定性。
1、簡介
Sentinel 主要由以下兩個部分組成:
- Sentinel 核心庫:Sentinel 的核心庫不依賴任何框架或庫,能夠運行于 Java 8 及以上的版本的運行時環(huán)境中,同時對 Spring Cloud、Dubbo 等微服務(wù)框架提供了很好的支持。
- Sentinel 控制臺(Dashboard):Sentinel 提供的一個輕量級的開源控制臺,它為用戶提供了機器自發(fā)現(xiàn)、簇點鏈路自發(fā)現(xiàn)、監(jiān)控、規(guī)則配置等功能。
1.1、基本概念
Sentinel 的基本概念有兩個,它們分別是:資源和規(guī)則。
基本概念 | 描述 |
---|---|
資源 | 資源是 Sentinel 的關(guān)鍵概念。它可以是 Java 應(yīng)用程序中的任何內(nèi)容,例如由應(yīng)用程序提供的服務(wù)或者是服務(wù)里的方法,甚至可以是一段代碼。 我們可以通過 Sentinel 提供的 API 來定義一個資源,使其能夠被 Sentinel 保護起來。通常情況下,我們可以使用方法名、URL 甚至是服務(wù)名來作為資源名來描述某個資源。 |
規(guī)則 | 圍繞資源而設(shè)定的規(guī)則。Sentinel 支持流量控制、熔斷降級、系統(tǒng)保護、來源訪問控制和熱點參數(shù)等多種規(guī)則,所有這些規(guī)則都可以動態(tài)實時調(diào)整。 |
2、Sentinel控制臺
下載:https://github.com/alibaba/Sentinel/releases
放到D:盤的sentinel目錄里面,并將其啟動
java -jar sentinel-dashboard-1.8.5.jar
啟動后,訪問地址:http://localhost:8080/
用戶名和密碼:sentinel/sentinel
3、Sentinel開發(fā)流程
引進sentinel依賴 -> 定義資源 -> 定義規(guī)則 -> 校驗規(guī)則
3.1、 drp-app-api消費端工程引進依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.0.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.5</version>
</dependency>
3.1.1、yml新加配置(跟nacos同級)
sentinel:
transport:
#配置 Sentinel dashboard 地址
dashboard: localhost:8080
#默認8719端口,假如被占用會自動從8719開始依次+1掃描,直至找到未被占用的端口
port: 8719
3.2、定義資源
- 適配主流框架自動定義資源
- 注解方式定義資源 (推薦)
@SentinelResource(value=“user-userInfoList”)
@SentinelResource(value = "tiger-test",blockHandler = "userInfoListBlockHandler")
public List<UserInfo> userInfoList(){
return this.userService.userInfoList();
}
public List<UserInfo> userInfoListBlockHandler(BlockException blockException){
log.info("#########################################userInfoListBlockHandler");
return null;
}
3.3、定義規(guī)則
3.3.1、流量控制
屬性 | 說明 | 默認值 |
---|---|---|
資源名 | 流控規(guī)則的作用對象。 | - |
閾值 | 流控的閾值。 | - |
閾值類型 | 流控閾值的類型,包括 QPS 或并發(fā)線程數(shù)。 | QPS |
針對來源 | 流控針對的調(diào)用來源。 | default,表示不區(qū)分調(diào)用來源 |
流控模式 | 調(diào)用關(guān)系限流策略,包括直接、鏈路和關(guān)聯(lián)。 | 直接 |
流控效果 | 流控效果(直接拒絕、Warm Up、勻速排隊),不支持按調(diào)用關(guān)系限流。 | 直接拒絕 |
3.3.2、流控模式
- 直接:統(tǒng)計當(dāng)前資源的請求,觸發(fā)閾值時對當(dāng)前資源直接限流,也是默認的模式
- 關(guān)聯(lián):統(tǒng)計與當(dāng)前資源相關(guān)的另一個資源,觸發(fā)閾值時,對當(dāng)前資源限流
使用場景:
a、兩個有競爭關(guān)系的資源
b、一個優(yōu)先級較高,一個優(yōu)先級較低
- 鏈路:統(tǒng)計從指定鏈路訪問到本資源的請求,觸發(fā)閾值時,對指定鏈路限流
例如有兩條請求鏈路: - /test1 --> /common
- /test2 --> /common
說明:Sentinel默認會將Controller方法做context整合,導(dǎo)致鏈路模式的流控失效,需要修改application.yml,添加配置:
spring:
cloud:
sentinel:
web-context-unify: false # 關(guān)閉context整合
3.3.3、流控效果
快速失?。哼_到閾值后,新的請求會被立即拒絕并拋出FlowException異常。是默認的處理方式。
warm up:預(yù)熱模式,對超出閾值的請求同樣是拒絕并拋出異常。但這種模式閾值會動態(tài)變化,從一個較小值逐漸增加到最大閾值。
排隊等待:讓所有的請求按照先后次序排隊執(zhí)行,兩個請求的間隔不能小于指定時長
當(dāng)請求超過QPS閾值時,快速失敗和warm up
會拒絕新的請求并拋出異常。而排隊等待則是讓所有請求進入一個隊列中,然后按照閾值允許的時間間隔依次執(zhí)行。后來的請求必須等待前面執(zhí)行完成,如果請求預(yù)期的等待時間超出最大時長,則會被拒絕。
例如:QPS = 5,意味著每200ms處理一個隊列中的請求;timeout =
2000,意味著預(yù)期等待超過2000ms的請求會被拒絕并拋出異常
打開命令行窗口,執(zhí)行以下命令查看資源的實時統(tǒng)計信息。
curl http://localhost:8719/cnode?id=userInfolist
idx id thread pass blocked success total aRt 1m-pass 1m-block 1m-all exceptio
2 userInfoList 0 0.0 0.0 0.0 0.0 0.0 10 16 26 0.0
實時統(tǒng)計信息各列名說明如下:
- thread: 代表當(dāng)前處理該資源的并發(fā)數(shù);
- pass: 代表一秒內(nèi)到來到的請求;
- blocked: 代表一秒內(nèi)被流量控制的請求數(shù)量;
- success: 代表一秒內(nèi)成功處理完的請求;
- total: 代表到一秒內(nèi)到來的請求以及被阻止的請求總和;
- RT: 代表一秒內(nèi)該資源的平均響應(yīng)時間;
- 1m-pass: 則是一分鐘內(nèi)到來的請求;
- 1m-block: 則是一分鐘內(nèi)被阻止的請求;
- 1m-all: 則是一分鐘內(nèi)到來的請求和被阻止的請求的總和;
- exception: 則是一秒內(nèi)業(yè)務(wù)本身異常的總和
3.3.4、熔斷降級
Sentinel 的熔斷將機制會在調(diào)用鏈路中某個資源出現(xiàn)不穩(wěn)定狀態(tài)時(例如調(diào)用超時或異常比例升高),暫時切斷對這個資源的調(diào)用,以避免局部不穩(wěn)定因素導(dǎo)致整個系統(tǒng)的雪崩。
Sentinel 提供了 3 種熔斷策略
熔斷策略 | 說明 |
---|---|
慢調(diào)用比例(SLOW_REQUEST_RATIO) | |
異常比例 (ERROR_RATIO) | 當(dāng)單位統(tǒng)計時長(statIntervalMs)內(nèi)請求數(shù)目大于設(shè)置的最小請求數(shù)目且異常的比例大于閾值,則在接下來的熔斷時長內(nèi)請求會自動被熔斷。 經(jīng)過熔斷時長后熔斷器會進入探測恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個請求成功完成(沒有錯誤)則結(jié)束熔斷,否則會再次被熔斷。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。 |
異常數(shù) (ERROR_COUNT) | 當(dāng)單位統(tǒng)計時長內(nèi)的異常數(shù)目超過閾值之后會自動進行熔斷。 經(jīng)過熔斷時長后熔斷器會進入探測恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個請求成功完成(沒有錯誤)則結(jié)束熔斷,否則會再次被熔斷。 |
狀態(tài) | 說明 | 觸發(fā)條件 |
---|---|---|
熔斷關(guān)閉狀態(tài)(CLOSED) | 處于關(guān)閉狀態(tài)時,請求可以正常調(diào)用資源。 | 滿足以下任意條件,Sentinel 熔斷器進入熔斷關(guān)閉狀態(tài):
|
熔斷開啟狀態(tài) (OPEN) | 處于熔斷開啟狀態(tài)時,熔斷器會一定的時間(規(guī)定的熔斷時長)內(nèi),暫時切斷所有請求對該資源的調(diào)用,并調(diào)用相應(yīng)的降級邏輯使請求快速失敗避免系統(tǒng)崩潰。 | 滿足以下任意條件,Sentinel 熔斷器進入熔斷開啟狀態(tài):
|
探測恢復(fù)狀態(tài)(HALF-OPEN) | 處于探測恢復(fù)狀態(tài)時,Sentinel 熔斷器會允許一個請求調(diào)用資源。則若接下來的一個請求成功完成(沒有錯誤)則結(jié)束熔斷,熔斷器進入熔斷關(guān)閉(CLOSED)狀態(tài);否則會再次被熔斷,熔斷器進入熔斷開啟(OPEN)狀態(tài)。 | 在熔斷開啟一段時間(降級窗口時間或熔斷時長,單位為 s)后,Sentinel 熔斷器自動會進入探測恢復(fù)狀態(tài)。 |
Sentinel 熔斷規(guī)則屬性
屬性 | 說明 | 默認值 | 使用范圍 |
---|---|---|---|
資源名 | 規(guī)則的作用對象。 | - | 所有熔斷策略 |
熔斷策略 | Sentinel 支持3 中熔斷策略:慢調(diào)用比例、異常比例、異常數(shù)策略。 | 慢調(diào)用比例 | 所有熔斷策略 |
最大 RT | 請求的最大相應(yīng)時間,請求的響應(yīng)時間大于該值則統(tǒng)計為慢調(diào)用。 | - | 慢調(diào)用比例 |
熔斷時長 | 熔斷開啟狀態(tài)持續(xù)的時間,超過該時間熔斷器會切換為探測恢復(fù)狀態(tài)(HALF-OPEN),單位為 s。 | - | 所有熔斷策略 |
最小請求數(shù) | 熔斷觸發(fā)的最小請求數(shù),請求數(shù)小于該值時即使異常比率超出閾值也不會熔斷(1.7.0 引入)。 | 5 | 所有熔斷策略 |
統(tǒng)計時長 | 熔斷觸發(fā)需要統(tǒng)計的時長(單位為 ms),如 60*1000 代表分鐘級(1.8.0 引入)。 | 1000 ms | 所有熔斷策略 |
比例閾值 | 分為慢調(diào)用比例閾值和異常比例閾值,即慢調(diào)用或異常調(diào)用占所有請求的百分比,取值范圍 [0.0,1.0]。 | - | 慢調(diào)用比例 、異常比例 |
異常數(shù) | 請求或調(diào)用發(fā)生的異常的數(shù)量。 | - | 異常數(shù) |
3.3.5、通過Nacos配置規(guī)則
[
{
"resource": "tiger-test",
"limitApp": "default",
"grade": 1,
"count": 5,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
limitApp:來源應(yīng)用;
- 流控規(guī)則
- 熔斷規(guī)則
(注:沒有RT這個參數(shù)哈)
[
{
"resource": "user-userInfoList",
"grade": 0,
"limitApp": "default",
"count":2000,
"slowRatioThreshold": 0.6,
"timeWindow": 60,
"minRequestAmount": 5,
"statIntervalMs":8000,
"clusterMode": false
}
]
工程配置讀取nacos的限流規(guī)則(跟sentinel同級)
datasource:
ds:
nacos:
server-addr: localhost:8848
data-id: user-sentinel
group-id: DEFAULT_GROUP
rule-type: flow
/**
* flow.
*/
FLOW("flow", FlowRule.class),
/**
* degrade.
*/
DEGRADE("degrade", DegradeRule.class),
/**
* param flow.
*/
PARAM_FLOW("param-flow", ParamFlowRule.class),
/**
* system.
*/
SYSTEM("system", SystemRule.class),
/**
* authority.
*/
AUTHORITY("authority", AuthorityRule.class),
配置多個nacos配置文件
datasource:
ds1:
nacos:
server-addr: localhost:8848
data-id: user-sentinel-flow
group-id: DEFAULT_GROUP
rule-type: flow
ds2:
nacos:
server-addr: localhost:8848
data-id: user-sentinel-degrade
group-id: DEFAULT_GROUP
rule-type: degrade
4、Sentinel與Gateway的整合
4.1、添加依賴
<!--gateway整合sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2021.0.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.0.4.0</version>
</dependency>
sentinel:
transport:
# 配置Sentinel dashboard地址
dashboard: localhost:8080
# 默認8719端口,鍵入被占用會自動從8719+1,直到找到未被占用的端口
port: 8719
4.2、詳細配置
接下來對sentinel控制臺中對gateway網(wǎng)關(guān)鏈路的流控配置項做詳細的介紹,下圖所示都是針對網(wǎng)關(guān)api附加的。
API類型
我們可以根據(jù)某個路由進行流控,也可以根據(jù)API分組進行流控,也就是請求訪問地址來進行流控
首先創(chuàng)建API分組
選擇API分組
然后在進行相應(yīng)的流控規(guī)則。
針對請求屬性
參數(shù)屬性有五種:客戶端ip、遠程請求地址、請求頭、請求url參數(shù)、Cookie
這里其實也就是對應(yīng)的gateway中路由的匹配規(guī)則
匹配模式提供了三種:精確、子串、正則
子串匹配模式就是:我們指定127,它會自動再結(jié)尾加上%進行模糊匹配——127%
Client IP
測試
Remote Host
因為我們沒有遠程域名,所以這里就不進行測試了
Header
使用postman請求進行測試,如果請求頭不為這個值就不會被限流
URL參數(shù)
測試
間隔
這個間隔的意思就是,以前1秒鐘請求三次就會拋異常,而現(xiàn)在是兩秒內(nèi)請求三次才會拋異常,也就是說間隔從以前的一秒改變了。
Burst size
Burst size相當(dāng)于是一個寬容次數(shù),以前是1秒鐘請求三次就會報異常,現(xiàn)在會寬容1次,也就是一秒鐘請求大于三次才會拋異常
網(wǎng)關(guān)流控規(guī)則 GatewayFlowRule 的核心屬性如下:
① resourceMode:規(guī)則是針對 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)還是用戶在 Sentinel 中定義的 API 分組(RESOURCE_MODE_CUSTOM_API_NAME),默認是 route。
② resource:資源名稱,可以是網(wǎng)關(guān)中的 route 名稱或者用戶自定義的 API 分組名稱。
③ grade:限流指標(biāo)維度,同限流規(guī)則的 grade 字段
④ count:限流閾值
⑤ intervalSec:統(tǒng)計時間窗口,單位是秒,默認是 1 秒
⑥ controlBehavior:流量整形的控制效果,目前支持快速失敗和勻速排隊兩種模式,默認是快速失敗。
⑦ burst:應(yīng)對突發(fā)請求時額外允許的請求數(shù)目。
⑧ maxQueueingTimeoutMs:勻速排隊模式下的最長排隊時間,單位是毫秒,僅在勻速排隊模式下生效。
⑨ paramItem:參數(shù)限流配置。若不提供,則代表不針對參數(shù)進行限流,該網(wǎng)關(guān)規(guī)則將會被轉(zhuǎn)換成普通流控規(guī)則;否則會轉(zhuǎn)換成熱點規(guī)則。其中的字段:
parseStrategy:從請求中提取參數(shù)的策略,目前支持提取來源 IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意 Header(PARAM_PARSE_STRATEGY_HEADER)和任意 URL 參數(shù)(PARAM_PARSE_STRATEGY_URL_PARAM)四種模式。
fieldName:若提取策略選擇 Header 模式或 URL 參數(shù)模式,則需要指定對應(yīng)的 header 名稱或 URL 參數(shù)名稱。
pattern:參數(shù)值的匹配模式,只有匹配該模式的請求屬性值會納入統(tǒng)計和流控;若為空則統(tǒng)計該請求屬性的所有值。
matchStrategy:參數(shù)值的匹配策略,目前支持精確匹配(PARAM_MATCH_STRATEGY_EXACT)、子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)和正則匹配(PARAM_MATCH_STRATEGY_REGEX)。
降級規(guī)則
(resource、grade、count、slowRatioThreshold、timeWindow、minRequestAmount、statIntervalMs)
自定義異常返回結(jié)果:
sentinel:
scg:
fallback:
mode: response
response-status: 200
response-body: '{"code":"500","message": "系統(tǒng)忙,請稍候再試"}'
代碼實現(xiàn):文章來源:http://www.zghlxwxcb.cn/news/detail-742867.html
/**
* 熔斷、降級回調(diào)
*/
@Configuration
public class SentinelGatewayConfig {
/**
* 這里可以寫降級邏輯
*/
public SentinelGatewayConfig() {
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
// 網(wǎng)關(guān)限制了請求,就會調(diào)用此回調(diào) Mono Flux
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
ResponseDTO<Object> objectResponseDTO = new ResponseDTO<>();
objectResponseDTO.setCode(500);
objectResponseDTO.setMessage("系統(tǒng)異常,請稍候重試");
String errJson = JSON.toJSONString(objectResponseDTO);
Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errJson), String.class);
return body;
}
});
}
}
將路由、限流、降級規(guī)則持久化到nacos配置中心文章來源地址http://www.zghlxwxcb.cn/news/detail-742867.html
spring:
application:
name: drp-gateway-service
profiles:
#開發(fā)環(huán)境dev,測試環(huán)境test,生產(chǎn)環(huán)境prod
active: dev
jackson:
time-zone: GMT+8
cloud:
loadbalancer:
ribbon:
enabled: false
nacos:
discovery:
server-addr: localhost:8848 #Nacos server 的地址
#路由配置
config:
server-addr: localhost:8848
name: gateway-router
namespace: public
group: DEFAULT_GROUP
#file-extension: json #指定yaml格式的配置
refresh-enabled: true #支持刷新
#限流熔斷配置
sentinel:
transport:
# 配置Sentinel dashboard地址
dashboard: localhost:8080
# 默認8719端口,鍵入被占用會自動從8719+1,直到找到未被占用的端口
port: 8719
datasource:
ds:
nacos:
server-addr: localhost:8848
data-id: user-sentinel
group-id: DEFAULT_GROUP
rule-type: flow
到了這里,關(guān)于Spring Cloud Alibaba 之 Sentinel的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!