前言
前面的文章我們學(xué)習(xí)了Hystrix并和springboot項(xiàng)目進(jìn)行了集成,實(shí)現(xiàn)服務(wù)的熔斷降級(jí)、隔離措施。但是Hystrix對(duì)流量的控制不是很好,僅僅信號(hào)量也只能對(duì)指定的接口進(jìn)行限流,至于保護(hù)機(jī)制Hystrix也只是達(dá)到指標(biāo)進(jìn)行熔斷。那么,有沒有一種中間件可以在兼容熔斷降級(jí)的同時(shí)精準(zhǔn)實(shí)現(xiàn)流量控制和負(fù)載保護(hù)呢?回答是當(dāng)然有的,就是我們今天的主角Spring Cloud Alibaba Sentinel。
知識(shí)積累
Sentinel 是面向分布式服務(wù)架構(gòu)的高可用流量防護(hù)組件,主要以流量為切入點(diǎn),從限流、流量整形、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)、熱點(diǎn)防護(hù)等多個(gè)維度來幫助開發(fā)者保障微服務(wù)的穩(wěn)定。
流量控制
Sentinel 可以針對(duì)不同的調(diào)用關(guān)系,按照指定的指標(biāo)進(jìn)行流程整形控制。而且整形的策略有直接拒絕、慢啟動(dòng)預(yù)熱和勻速器三大模式,開發(fā)者可用根據(jù)自身需求選用策略實(shí)現(xiàn)流量的精準(zhǔn)控制。
負(fù)載保護(hù)
Sentinel 可用提供精準(zhǔn)的負(fù)載保護(hù)機(jī)制,如果被調(diào)用服務(wù)達(dá)到最大負(fù)載會(huì)將請(qǐng)求負(fù)載均衡到其他服務(wù)提供者上面,如果其他服務(wù)也達(dá)到了最大負(fù)載則會(huì)啟動(dòng)服務(wù)保護(hù)機(jī)制讓請(qǐng)求流量和服務(wù)的負(fù)載達(dá)到平衡。
熔斷降級(jí)
Sentinel 也是提供了基礎(chǔ)的熔斷降級(jí)功能,如果服務(wù)提供著拋出一次會(huì)直接降級(jí)走fallback邏輯,如果是配置指標(biāo)則走blockhander邏輯。當(dāng)然,如果服務(wù)集群達(dá)到最大負(fù)載會(huì)執(zhí)行熔斷功能,防止服務(wù)雪崩的發(fā)生。
官方文檔
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
實(shí)戰(zhàn)演練
部署sentinel-dashboard
下載jar包
https://github.com/alibaba/Sentinel/releases
直接jar包部署
nohup java -jar -Dserver.port=8109 sentinel-dashboard.jar &
docker-compose編排
有條件的可以直接使用dashboard鏡像,如果pull緩慢則考慮自己構(gòu)建鏡像。
dockerfile
# this is sentinel-dashboard dockerfile
# version 1.0
# 基礎(chǔ)鏡像
FROM openjdk:8-jre
# 維護(hù)人
MAINTAINER senfel<187@sina.cn>
#jar
COPY ./sentinel-dashboard.jar /home/app.jar
# 端口
EXPOSE 8109
# 執(zhí)行命令啟動(dòng)jar
ENTRYPOINT ["java","-jar","/home/app.jar"]
docker-compose.yml
version: '3.3'
services:
sentinel:
build: ./
image: senfel/sentinel-dashboard
container_name: sentinel-dashboard
ports:
- 8109:8109
environment:
JVM_OPTS: -server -Xmx512M -Xms512M -XX:MaxMetaspaceSize=256M -XX:CompressedClassSpaceSize=50M -XX:ReservedCodeCacheSize=240M -XX:MaxDirectMemorySize=400M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "1"
volumes:
- "/home/test/demo/sentinel/logs:/root/logs"
- "/home/test/demo/sentinel/logs:/app-logs"
command: [
"--server.port=8109",
"--logging.file.path=/app-logs"
]
構(gòu)件并啟動(dòng)容器
docker-compose up -d --build
查看sentinel容器
docker ps | grep sentinel
springboot集成sentinel
基礎(chǔ)架構(gòu)搭建
持久化流量控制規(guī)則,其他規(guī)則只需要增加配置即可
sentinel持久化到nacos 不持久每次重啟都會(huì)清除規(guī)則
增加maven依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--sentinel持久化到nacos 不持久每次重啟都會(huì)清除規(guī)則-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
增加bootstrap.yml配置 nacos自行搭建
server:
port: 9999
spring:
application:
name: test-demo
profiles:
active: uat
cloud:
nacos:
config:
server-addr: 10.10.18.16:8848,10.10.18.16:2848,10.10.18.16:5848
username: nacos
password: nacos
file-extension: yaml
discovery:
server-addr: 10.10.18.16:8848,10.10.18.16:2848,10.10.18.16:5848
username: nacos
password: nacos
sentinel:
transport:
dashboard: 10.10.22.174:8109
port: 8719
datasource:
ds1:
nacos:
server-addr: 10.10.18.16:8848,10.10.18.16:2848,10.10.18.16:5848
dataId: test-demo-sentinel.json
data-type: json
rule-type: flow
username: nacos
password: nacos
#開啟sentinel
feign:
sentinel:
enabled: true
circuitbreaker:
enabled: true
nacos新增限流配置
流量控制
resource:資源名稱
limitApp:來源應(yīng)用
grade:閾值類型,0代表線程數(shù),1代表QPS
count:?jiǎn)螕糸撝?br> strategy:流控模式,0代表直接,1代表關(guān)聯(lián),2代表鏈路
controlBehavior:流控效果,0代表快速失敗,1代表Warm Up,2代表排隊(duì)等待
clusterMode:是否集群
-其他規(guī)則大同小異這里不再累述
-nacos配置與本文無關(guān)不再累述
[
{
"resource": "testFeign",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
啟動(dòng)類開啟feign與nacos
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@Slf4j
public class TestDemoApplication implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(TestDemoApplication.class, args);
}
}
測(cè)試用例
/**
* testFeign
* fallback只負(fù)責(zé)業(yè)務(wù)異常
* blockHandler只負(fù)責(zé)sentinel配置超標(biāo)
* 兩個(gè)都配置,如果都出錯(cuò),會(huì)進(jìn)入blockHandler
* @param str
* @author senfel
* @date 2023/7/11 14:26
* @return java.lang.String
*/
@SentinelResource(value = "testFeign",blockHandler = "blockHandler",fallback = "handlerFallback")
@GetMapping("/testFeign")
public String testFeign(String str){
if(str.contains("y")){
throw new RuntimeException();
}
return testMQService.testFeign(str);
}
/**
* 異常阻塞處理
* @param str
* @author senfel
* @date 2023/7/11 14:44
* @return java.lang.String
*/
private String blockHandler(String str, BlockException blockException){
return "blockHandler"+"-"+str;
}
/**
* 降級(jí)處理
* @param str
* @author senfel
* @date 2023/7/11 14:44
* @return java.lang.String
*/
private String handlerFallback(String str,Throwable throwable){
return "handlerFallback"+"-"+str;
}
openfeign降級(jí)測(cè)試用例
/**
* @author senfel
* @version 1.0
* @date 2023/7/03 15:04
*/
@Service
@FeignClient(value = "test-demo",fallback = FallbackService.class)
public interface TestService {
/**
* 測(cè)試sentinel
*/
@GetMapping("/feign")
String feign(@RequestParam String str);
}
/**
* FallbackService
* @author senfel
* @version 1.0
* @date 2023/7/3 15:26
*/
@Service
public class FallbackService implements TestService {
@Override
public String feign(String str) {
return ">>>>>客戶端服務(wù)降級(jí)>>>>>";
}
}
sentinel控制臺(tái)
postman請(qǐng)求后查看 http://10.10.22.174:8109/
自動(dòng)加載配置的流量規(guī)則
sentinel驗(yàn)證
驗(yàn)證主動(dòng)控制流量
127.0.0.1:9999/testFeign?str=fffffffffss
驗(yàn)證異??刂屏髁?br> 127.0.0.1:9999/testFeign?str=fffffffffyy
驗(yàn)證客戶端feign降級(jí)
127.0.0.1:9999/testFeign?str=fffffffffss
查看實(shí)時(shí)監(jiān)控
延伸:系統(tǒng)自適應(yīng)限流
系統(tǒng)規(guī)則
系統(tǒng)保護(hù)規(guī)則是從應(yīng)用級(jí)別的入口流量進(jìn)行控制,從單臺(tái)機(jī)器的 load、CPU 使用率、平均 RT、入口 QPS 和并發(fā)線程數(shù)等幾個(gè)維度監(jiān)控應(yīng)用指標(biāo),讓系統(tǒng)盡可能跑在最大吞吐量的同時(shí)保證系統(tǒng)整體的穩(wěn)定性。
系統(tǒng)保護(hù)規(guī)則是應(yīng)用整體維度的,而不是資源維度的,并且僅對(duì)入口流量生效。入口流量指的是進(jìn)入應(yīng)用的流量(EntryType.IN),比如 Web 服務(wù)或 Dubbo 服務(wù)端接收的請(qǐng)求,都屬于入口流量。
系統(tǒng)規(guī)則支持以下的模式:
Load 自適應(yīng)(僅對(duì) Linux/Unix-like 機(jī)器生效):系統(tǒng)的 load1 作為啟發(fā)指標(biāo),進(jìn)行自適應(yīng)系統(tǒng)保護(hù)。當(dāng)系統(tǒng) load1 超過設(shè)定的啟發(fā)值,且系統(tǒng)當(dāng)前的并發(fā)線程數(shù)超過估算的系統(tǒng)容量時(shí)才會(huì)觸發(fā)系統(tǒng)保護(hù)(BBR 階段)。系統(tǒng)容量由系統(tǒng)的 maxQps * minRt 估算得出。設(shè)定參考值一般是 CPU cores * 2.5。
CPU usage(1.5.0+ 版本):當(dāng)系統(tǒng) CPU 使用率超過閾值即觸發(fā)系統(tǒng)保護(hù)(取值范圍 0.0-1.0),比較靈敏。
平均 RT:當(dāng)單臺(tái)機(jī)器上所有入口流量的平均 RT 達(dá)到閾值即觸發(fā)系統(tǒng)保護(hù),單位是毫秒。
并發(fā)線程數(shù):當(dāng)單臺(tái)機(jī)器上所有入口流量的并發(fā)線程數(shù)達(dá)到閾值即觸發(fā)系統(tǒng)保護(hù)。
入口 QPS:當(dāng)單臺(tái)機(jī)器上所有入口流量的 QPS 達(dá)到閾值即觸發(fā)系統(tǒng)保護(hù)。
原理
我們把系統(tǒng)處理請(qǐng)求的過程想象為一個(gè)水管,到來的請(qǐng)求是往這個(gè)水管灌水,當(dāng)系統(tǒng)處理順暢的時(shí)候,請(qǐng)求不需要排隊(duì),直接從水管中穿過,這個(gè)請(qǐng)求的RT是最短的;反之,當(dāng)請(qǐng)求堆積的時(shí)候,那么處理請(qǐng)求的時(shí)間則會(huì)變?yōu)椋号抨?duì)時(shí)間 + 最短處理時(shí)間。
配置頁面
寫在最后
Sentinel實(shí)現(xiàn)流量控制、熔斷降級(jí)、負(fù)載保護(hù)的實(shí)際使用個(gè)人覺得還是比較簡(jiǎn)單,只需要根據(jù)官方文章集成和配置使用即可。sentinel的流量控制和負(fù)載保護(hù)以及高性能都優(yōu)于hystrix,并提供可視化控制臺(tái)。如果在可用性和可靠性較高和重要的服務(wù)集群場(chǎng)景中,可以優(yōu)先考慮sentinel。文章來源:http://www.zghlxwxcb.cn/news/detail-572251.html
??路漫漫其修遠(yuǎn)兮,吾將上下而求索 ??文章來源地址http://www.zghlxwxcb.cn/news/detail-572251.html
到了這里,關(guān)于實(shí)戰(zhàn):Springboot集成Sentinel實(shí)現(xiàn)流量控制、熔斷降級(jí)、負(fù)載保護(hù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!