Sentinel的安裝
1、下載使用
下載sentinel地址:https://github.com/alibaba/Sentinel/releases
下載 sentinel-dashboard-1.7.2.jar
?通過java -jar啟動(dòng)sentinel 烙样,默認(rèn)sentinel占用的端口是8080 --server.port=8888是將端口設(shè)置為8888播赁,如果有改端口需求則更改對(duì)應(yīng)端口即可
1java? -jar .\sentinel-dashboard-1.7.2.jar --server.port=8888
用戶和密碼都是sentinel
2、maven方式
加入依賴管理和依賴
<dependencyManagement>
????????<dependencies>
????????????<dependency>
????????????????<groupId>com.alibaba.cloud</groupId>
????????????????<artifactId>spring-cloud-alibaba-dependencies</artifactId>
????????????????<version>2.2.1.RELEASE</version>
????????????????<type>pom</type>
????????????????<scope>import</scope>
????????????</dependency>
????????</dependencies>
????</dependencyManagement>
<!--?? spring-cloud-starter-alibaba-nacos-discovery? nacos服務(wù)注冊(cè)中心?? -->
<dependency>
????<groupId>com.alibaba.cloud</groupId>
????<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- spring-cloud-starter-alibaba-sentinel sentinel客戶端-->
<dependency>
????<groupId>com.alibaba.cloud</groupId>
????<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- sentinel-datasource-nacos sentinel持久化數(shù)據(jù) -->
<dependency>
????<groupId>com.alibaba.csp</groupId>
????<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
注意自己修改端口等對(duì)應(yīng)的信息薪铜,在這里sentinel使用來自定義的8888端口
server:
??port: 8400
spring:
??application:
????name: sentinel-client? #應(yīng)用名
??cloud:
????nacos:
??????discovery: #服務(wù)注冊(cè)中心地址
????????server-addr: 127.0.0.1:8848
??????config:? #nacos的配置中心地址众弓,如果不需要用到則暫時(shí)注釋掉
????????server-addr: 127.0.0.1:8848
????????file-extension: yml
????sentinel:
??????transport:
????????dashboard: 127.0.0.1:8888
????????port: 8719
啟動(dòng)類
@SpringBootApplication
@EnableDiscoveryClient
publicclassSentinelClient8400 {
????publicstaticvoidmain(String[] args) {
????????SpringApplication.run(SentinelClient8400.class, args);
????}
}
需要流控的Controller類,示例代碼
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.RestController;
@RestController
publicclassSentinelDemoController {
????@GetMapping("/test001")
????publicString test001(){
????????return"test001";
????}
????@GetMapping("/test002")
????publicString test002() {
????????return"test002";
????}
}
然后啟動(dòng)nacos,再啟動(dòng)sentinel jar包隔箍,然后再啟動(dòng)上面這個(gè)啟動(dòng)類
需要注意的是sentinel是懶加載的機(jī)制谓娃,也意味著需要訪問一些上面Controller中的 /test001 才會(huì)在sentinel后臺(tái)看到服務(wù)
瀏覽器訪問一下 http://localhost:8400/test001
然后刷新一下sentinel后臺(tái) http://localhost:8080/#/dashboard/home
原文鏈接:https://blog.csdn.net/qq_41813208/article/details/106994203
使用方法
簡(jiǎn)介
Sentinel是面向分布式服務(wù)框架的輕量級(jí)流量控制框架,主要以流量為切入點(diǎn),從流量控制,熔斷降級(jí),系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來維護(hù)系統(tǒng)的穩(wěn)定性。
在SpringCloud體系中蜒滩,sentinel主要是為了替換原Hystrix的功能滨达,與Hystrix相比,sentinel的隔離級(jí)別更加精細(xì)俯艰,提供的Dashboard可以在線更改限流熔斷規(guī)則捡遍,而且使用也越加方便。要了解更多詳細(xì)信息請(qǐng)移步至Sentinel官網(wǎng)竹握。
基礎(chǔ)準(zhǔn)備
要使用Sentinel提供的限流熔斷能力画株,需要先做如下準(zhǔn)備:
安裝Sentinel
這部分內(nèi)容我已經(jīng)在第一期SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)一 - 基礎(chǔ)環(huán)境準(zhǔn)備中提過,大家可以翻閱查看啦辐。
引入Sentinel
在需要配置限流熔斷服務(wù)的POM文件中引入Sentinel組件
<!--Sentinel-->org.springframework.cloudspring-cloud-starter-alibaba-sentinel
自定義資源@SentinelResource
我們只需要在相關(guān)方法上加上@SentinelResource注解谓传,讓其可以成為sentinel識(shí)別的資源即可。如:
@GetMapping("/account/getByCode/{accountCode}")@SentinelResource(value = "getByCode")publicResultDatagetByCode(@PathVariable(value = "accountCode")String accountCode){? ? log.info("get account detail,accountCode is :{}",accountCode);? ? AccountDTO accountDTO = accountService.selectByCode(accountCode);returnResultData.success(accountDTO);}
在配置文件中添加sentinel的服務(wù)端地址
server:port:8010spring:application:name:account-servicecloud:nacos:discovery:server-addr:192.168.0.107:8848/sentinel:transport:# sentinel服務(wù)端地址dashboard:192.168.0.107:8858# 取消延遲加載eager:true
經(jīng)過以上幾步我們準(zhǔn)備好了使用Sentinel的基礎(chǔ)環(huán)境昧甘,接下來我們看看限流熔斷的具體配置良拼。
限流
概念說明
生產(chǎn)者accout-service是一個(gè)核心服務(wù),我們通過壓測(cè)得出服務(wù)的最大負(fù)載能力為60充边。如果某個(gè)時(shí)間account-service的請(qǐng)求數(shù)飆升達(dá)到了600庸推,那服務(wù)肯定就直接gg了常侦。所以為了保護(hù)我們的accout-service,我們會(huì)給它配置一個(gè)限流規(guī)則贬媒,如果每秒鐘有超過60的請(qǐng)求那不好意思我直接丟掉不處理了聋亡,然后丟給消費(fèi)者一個(gè)異常,想拖垮我际乘,哼坡倔,沒門!脖含。
總而言之罪塔,限流是通過限制調(diào)用方對(duì)自己的調(diào)用,起到保護(hù)自己系統(tǒng)的效果养葵。
限流配置
理想是豐滿的征堪,現(xiàn)實(shí)是骨感的。由于本人對(duì)Jmeter之類的壓測(cè)工具不是很精通所以為了方便測(cè)試关拒,我們就將accout-service的QPS單機(jī)閾值設(shè)置成5佃蚜,如果每秒QPS超過5,直接丟棄着绊。
這里的資源名就是我們使用@SentinelResource注解自定義的資源谐算。
打開瀏覽器,快速刷新瀏覽器归露,當(dāng)每秒請(qǐng)求書超過5時(shí)會(huì)看到如下錯(cuò)誤:
在后端服務(wù)日志中你會(huì)看到如下的錯(cuò)誤日志:
2019-12-1014:22:31,948ERROR[dispatcherServlet]:175- Servlet.service()forservlet[dispatcherServlet]incontext with path[]threw exception[Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException]with root causecom.alibaba.csp.sentinel.slots.block.flow.FlowException: null
不要慌洲脂,這說明我們的目的達(dá)到了,限流成功靶擦!
自定義異常
我們可以通過@SentinelResource中添加blockHandler參數(shù)腮考,給其添加自定義異常方法。如:
@GetMapping("/account/getByCode/{accountCode}")@SentinelResource(value = "getByCode",blockHandler = "handleException")publicResultDatagetByCode(@PathVariable(value = "accountCode")String accountCode){? ? log.info("get account detail,accountCode is :{}",accountCode);? ? AccountDTO accountDTO = accountService.selectByCode(accountCode);returnResultData.success(accountDTO);}/**
* 自定義異常策略
* 返回值和參數(shù)要跟目標(biāo)函數(shù)一樣玄捕,參數(shù)可以追加BlockException
*/publicResultDatahandleException(String accountCode,BlockException exception){? ? log.info("flow exception{}",exception.getClass().getCanonicalName());returnResultData.fail(900,"達(dá)到閾值了,不要再訪問了!");}
注意踩蔚,自定義的異常方法的參數(shù)和返回值要跟目標(biāo)方法一樣,參數(shù)可以追加BlockException
效果如下:
比之前的那個(gè)錯(cuò)誤頁(yè)優(yōu)雅多了有木有枚粘!
持久化配置
由于Sentinel的配置默認(rèn)是放在內(nèi)存中的馅闽,每當(dāng)應(yīng)用重啟或者sentinel重啟都會(huì)丟失數(shù)據(jù),我們這里使用Nacos作為配置中心持久化限流配置馍迄。
修改pom文件福也,引入sentinel-datasource-nacos組件
com.alibaba.cspsentinel-datasource-nacos
修改application.yml,配置sentinel的數(shù)據(jù)源
spring:cloud:sentinel:datasource:ds:nacos:server-addr:10.0.10.48:8848data-id:${spring.application.name}-sentinelgroup-id:DEFAULT_GROUPrule-type:flow
在nacos中建立限流配置account-service-sentinel(配置格式設(shè)置成json)
[? ? {"resource":"getByCode","limitApp":"default","grade":1,"count":3,"strategy":0,"controlBehavior":0,"clusterMode":false}]
可以看到上面配置規(guī)則是一個(gè)數(shù)組類型攀圈,數(shù)組中的每個(gè)對(duì)象是針對(duì)每一個(gè)保護(hù)資源的配置對(duì)象暴凑,每個(gè)對(duì)象中的屬性解釋如下:
resource:資源名,即限流規(guī)則的作用對(duì)象
limitApp:流控針對(duì)的調(diào)用來源赘来,若為 default 則不區(qū)分調(diào)用來源
grade:限流閾值類型(QPS 或并發(fā)線程數(shù))现喳;0代表根據(jù)并發(fā)數(shù)量來限流凯傲,1代表根據(jù)QPS來進(jìn)行流量控制
count:限流閾值
strategy:調(diào)用關(guān)系限流策略
controlBehavior:流量控制效果(直接拒絕、Warm Up嗦篱、勻速排隊(duì))
clusterMode:是否為集群模式
進(jìn)入sentinel查看dashboard冰单,發(fā)現(xiàn)sentinel自動(dòng)獲取nacos的配置
頻繁刷新瀏覽器調(diào)用接口,驗(yàn)證接口是否正常限流
熔斷
概念說明
消費(fèi)者order-service需要先調(diào)用product-service獲取具體的product灸促,然后再處理其他的業(yè)務(wù)邏輯诫欠。但是這個(gè)product-service接口不是很穩(wěn)定,經(jīng)常拋出異常浴栽;或者是響應(yīng)緩慢,導(dǎo)致order-service的響應(yīng)變慢吃度;如果置之不理椿每,order-service可能會(huì)被product-service拖垮。這時(shí)候?yàn)榱吮Wo(hù)order-service英遭,我們需要對(duì)product-service接口進(jìn)行熔斷间护。
一言以蔽之:熔斷是通過限制自己對(duì)外部系統(tǒng)的調(diào)用挖诸, 起到節(jié)約響應(yīng)時(shí)間、維護(hù)鏈路穩(wěn)定的作用多律。
熔斷配置
Sentinel中的熔斷降級(jí)有三個(gè)降級(jí)策略:
RT(平均響應(yīng)時(shí)間):
當(dāng)資源的平均響應(yīng)時(shí)間超過閾值之后痴突,資源進(jìn)入準(zhǔn)降級(jí)狀態(tài)。接下來如果持續(xù)進(jìn)入 5 個(gè)請(qǐng)求辽装,它們的 RT 都持續(xù)超過這個(gè)閾值相味,那么在接下的時(shí)間窗口之內(nèi),對(duì)這個(gè)方法的調(diào)用都會(huì)自動(dòng)拋出 DegradeException 異常拓巧。在下一個(gè)時(shí)間窗口到來時(shí), 會(huì)接著再放入5個(gè)請(qǐng)求, 再重復(fù)上面的判斷.
異常比例
當(dāng)資源的每秒異骋凰溃總數(shù)占通過量的比值超過閾值之后投慈,資源進(jìn)入降級(jí)狀態(tài)冠骄,即在接下的時(shí)間窗口之內(nèi)瘩绒,對(duì)這個(gè)方法的調(diào)用都會(huì)自動(dòng)地拋出DegradeException異常锁荔。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%跋理。
異常數(shù)
當(dāng)資源近 1 分鐘的異常數(shù)目超過閾值之后會(huì)進(jìn)行熔斷恬总。
首先我們對(duì)原接口進(jìn)行改造,讓其直接拋出Runtimeexception:
@GetMapping("/product/getByCode/{productCode}")@SentinelResource(value = "/product/getByCode",fallback = "fallbackHandler")publicResultDatagetByCode(@PathVariableString productCode){? ? log.info("get product detail,productCode is :{}",productCode);? ? ProductDTO productDTO = productService.selectByCode(productCode);thrownewRuntimeException("error");//? ? ? ? return ResultData.success(productDTO);}
這里我們將product-service設(shè)置如下的熔斷規(guī)則:
如果/product/getByCode的異常率超過50%,那么接下來2秒內(nèi)直接觸發(fā)熔斷降級(jí)贱纠,默認(rèn)情況會(huì)拋出DegradeException異常谆焊,如:
2019-12-1019:35:53,764ERROR[dispatcherServlet]:175- Servlet.service()forservlet[dispatcherServlet]incontext with path[]threw exception[Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException]with root causecom.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null
自定義異常
自定義熔斷異常跟限流異常類似,我們使用fallback屬性指定自定義異常的方法辜王,如:
@SentinelResource(value = "/product/getByCode",fallback = "fallbackHandler")publicResultDatagetByCode(@PathVariableString productCode){ ...}/**
* 自定義熔斷異常
* 返回值和參數(shù)要跟目標(biāo)函數(shù)一樣
*/publicResultDatafallbackHandler(String productCode){returnResultData.fail(800,"服務(wù)被熔斷了呐馆,不要調(diào)用!");}
注意肾档,自定義的異常方法的參數(shù)和返回值要跟目標(biāo)方法一樣
效果如下:
持久化配置
引入sentinel-datasource-nacos組件怒见,跟限流一樣配置即可
修改application.yml,配置sentinel的數(shù)據(jù)源
spring:cloud:sentinel:datasource:ds:nacos:server-addr:192.168.0.106:8848data-id:${spring.application.name}-sentinel-degradegroup-id:DEFAULT_GROUPrule-type:degrade
在nacos中建立配置文件product-service-sentinel-degrade,做如下配置
[? ? {"resource":"/product/getByCode","count":0.5,"grade":1,"passCount":0,"timeWindow":2}]
可以看到上面配置規(guī)則是一個(gè)數(shù)組類型闺阱,數(shù)組中的每個(gè)對(duì)象是針對(duì)每一個(gè)保護(hù)資源的配置對(duì)象酣溃,每個(gè)對(duì)象中的屬性解釋如下:
resource:資源名,即降級(jí)規(guī)則的作用對(duì)象
count:閾值
grade:降級(jí)模式 0:RT 1:異常比例 2:異常數(shù)
timeWindow:時(shí)間窗口(單位秒)
進(jìn)入sentinel查看dashboard扛或,發(fā)現(xiàn)sentinel自動(dòng)獲取nacos的配置
血與淚
大家在使用sentinel過程中如果出現(xiàn)Failed to fetch metric from?的錯(cuò)誤,具體表現(xiàn)如下:
Failedtofetchmetricfrom (ConnectionException:Connectionrefused:nofurther information)
這個(gè)時(shí)候你需要去檢查下sentinel控制臺(tái)的服務(wù)列表熙兔,確認(rèn)是否跟你ip一致住涉。(我之前是裝過虛擬機(jī)钠绍,sentinel一直抓取的是我虛擬的ip,不知道為什么媳握。磷脯。争拐。)
如果發(fā)現(xiàn)監(jiān)聽的地址不對(duì)的話架曹,可以在sentinel客戶端配置中加入客戶端ip配置
spring:cloud:sentinel:transport:client-ip:192.168.0.108
至此我們已經(jīng)給我們的微服務(wù)加上了限流熔斷保護(hù)闹瞧,再也不用擔(dān)心異常流量的沖擊奥邮,下游系統(tǒng)不穩(wěn)定導(dǎo)致自身服務(wù)不可用了。