springcloud的基础学习--sentinel的使用
安装sentinel
使用docker 安装sentinel
docker pull docker.io/bladex/sentinel-dashboard
docker run --name sentinel_test_1 -di -p 8858:8858 aa398704ebd3 (镜像id)
使用jar包的方式安装
Java -jar sentinel的jar包路径
用户名和密码
sentinel/sentinel
项目资源名称:
资源名:唯一名称,默认请求路径
针对来源:sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
阈值类型/单机阈值:
QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流
线程数:当调用该api的线程数达到阈值的时候,进行限流
是否集群:不需要集群
流控模式:
直接:api达到限流的时候,直接限流
关联:当关联的资源达到阈值的时候,就限流自己
链路:只记录指定链路上的流量(指定资源从入口进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
流控效果:
快速失败:直接失败,抛异常
Warm up: 根据codeFactor(冷加载因子,默认3)的值,从阈值/codefactor,经过预热时长,才达到设置的QPS阈值
排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效
对于项目中的使用
maven配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>LearnCloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.huhu</groupId>
<artifactId>cloud-sentinel-alibaba-8401</artifactId>
<version>1.0-SNAPSHOT</version>
<name>cloud-sentinel-alibaba-8401</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>
配置文件
server:
port: 8401
spring:
application:
name: cloud-sentinel-alibaba
cloud:
nacos:
discovery:
#nacos服务注册中心
server-addr: 127.0.0.1:8848
sentinel:
transport:
#配置sentinel dashboard的地址
dashboard: 127.0.0.1:8080
#默认8719端口,假如被占用会自动从8719开始依次扫描,直至找到未被占用的端口
port: 8719
clientIp: 127.0.0.1
management:
endpoint:
web:
exposure:
include: '*'
主启动
//注解只有两个
@SpringBootApplication
@EnableDiscoveryClient
测试类:
package com.huhu.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class flowlimitController {
@GetMapping("/testA")
public String testA(){
return "------testA";
}
@GetMapping("/testB")
public String testB(){
return "------testB";
}
}
使用sentinel进行流量监控
直接监控
一个api访问达到阈值,直接限制
关联的使用
A接口关联B,当B接口的访问达到阈值的时候,先限制A接口访问
现实案例:支付接口和订单接口:当支付接口调用不过来的时候,就限制下订单的接口
预热的使用
使用QPS,5秒内慢慢的升到10.
默认的coldFactor为3,即请求的QPS从(threshlod/3)开始,经多少预热时长才逐渐升至设定的QPS阈值
案例:阈值10+预热时长设置5秒
系统初始化阈值为10/3约等于3,然后过了5秒后阈值才慢慢升高回复到10
排队等待
匀速排队,严格的控制请求通过的间隔时间,
也就是让请求以均匀的速度通过,对应是漏桶算法,
熔断降级–针对于sentinel
RT
概念:平均响应时间
触发条件: 超出阈值 且 在时间串口内通过的请求>=5 两个条件都满足触发降级
结束:窗口期后关闭断路器
最大时间:RT最大4900,更大需要通过-DCSp.sentinel.static.max.rt=XXXX才能生效
异常比例:
异常数
概念:当资源进一分钟的异常数目超过阈值之后会进行熔断
热点规则
概念:何为热点,经常访问的数据,对访问很经常的数据进行限制
@SentinelResource:
blockHandler参数为服务超过次数时替代方法。
普通使用:
@GetMapping("/toHotKey")
@SentinelResource(value = "toHotKey",blockHandler = "deltohoht")
public String toHotKey(@RequestParam(value = "p1",required = false)String p1,
@RequestParam(value = "p2",required = false)String p2){
return "hotket";
}
public String deltohoht(String p1, String p2, BlockException ex){
return "触发热点规则";
}
高级使用:
当参数为某个特殊的值的时候,限流和平时不一样
如:当怕p1为1的时候,他的阈值可以到200
@SentinelResources的使用
普通使用:
//普通的使用,无兜底的方法
@GetMapping(value = "test/putong")
@SentinelResource(value = "putong")
public AjaxModel huuhu(){
return AjaxModel.success("普通的使用成功----0");
}
//普通的使用,有兜底的方法
@GetMapping(value = "test/putong1")
@SentinelResource(value = "putong1",blockHandler = "putong11")
public AjaxModel huuhu1(){
return AjaxModel.success("普通的使用成功----1");
}
public AjaxModel putong11(BlockException e){
return AjaxModel.error("普通使用的错误回调---1");
}
注意点:
1.使用有兜底的方法的时候,使用下面的配置
2.高级使用
代码解耦
全局处理的异常:
package com.huhu.exception;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.huhu.model.AjaxModel;
public class MyCloudException {
public static AjaxModel execpt1(BlockException e){
return AjaxModel.error(444,"错误异常1");
}
public static AjaxModel execpt2(BlockException e){
return AjaxModel.error(444,"错误异常2");
}
}
代码的应用:
@GetMapping(value = "test/myexec")
@SentinelResource(value = "myexec",blockHandlerClass = MyCloudException.class,blockHandler = "execpt2")
public AjaxModel testQ(){
return AjaxModel.success("未发生错误");
}
几个注意点:
1.全局的异常的处理,方法必须为static,且参数需要带BlockException
2.这里的Block是针对于sentinel的
服务降级
fallback的使用
@Autowired
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String url;
@GetMapping("sent/fallback/{id}")
@SentinelResource(value = "fallback",fallback = "fallbackHandler")
public AjaxModel fallback(@PathVariable(value = "id")int id){
if(id > 3){
throw new RuntimeException("没有查询到数据");
}
String msg = restTemplate.getForObject(url + "/test/getport", String.class);;
return AjaxModel.success(msg+ "fallback is success and id is " + id);
}
public AjaxModel fallbackHandler(@PathVariable(value = "id")int id){
return AjaxModel.error("something is error in id " + id);
}
同时使用blockhandler
@GetMapping("sent/fallback/{id}")
@SentinelResource(value = "fallback",fallback = "fallbackHandler",blockHandler = "")
public AjaxModel fallback(@PathVariable(value = "id")int id){
if(id > 3){
throw new RuntimeException("没有查询到数据");
}
String msg = restTemplate.getForObject(url + "/test/getport", String.class);;
return AjaxModel.success(msg+ "fallback is success and id is " + id);
}
说明:
fallback的话,是针对于java级的代码异常处理
blockhandler的话,主要是针对于sentinel的处理
两个放在一起的话,出现的数据是block的数据
sentinel整合openfegin
pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置文件
server:
port: 83
spring:
application:
name: nacos-consumer
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
#配置sentinel dashboard的地址
dashboard: 127.0.0.1:8080
#默认8719端口,假如被占用会自动从8719开始依次扫描,直至找到未被占用的端口
port: 8719
clientIp: 127.0.0.1
#消费者要去访问的微服务的名称
service-url:
nacos-user-service: http://nacos-payment-provider
#激活sentinel对feign的支持
feign:
sentinel:
enabled: true
主启动
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //激活openfeign的功能
public class cloudconsumeralibaba83
{
public static void main( String[] args )
{
SpringApplication.run(cloudconsumeralibaba83.class,args);
}
}
测试代码
//接口
@FeignClient(value = "nacos-payment-provider",fallback = payFallbackService.class)
public interface payService {
@GetMapping("test/getport")
public String getPort();
}
//回调类
@Component
public class payFallbackService implements payService{
@Override
public String getPort() {
return "open的服务降级";
}
}
//测试代码
@Autowired
private payService userService;
@GetMapping("/timeout1")
public String asdas(){
return userService.getPort();
}
测试
没有停止对应的微服务提供者
正常访问
停止
sentinel的持久化规则
pom文件
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
完整的配置文件
server:
port: 8401
spring:
application:
name: cloud-sentinel-alibaba
cloud:
nacos:
discovery:
#nacos服务注册中心
server-addr: 127.0.0.1:8848
sentinel:
transport:
#配置sentinel dashboard的地址
dashboard: 127.0.0.1:8080
#默认8719端口,假如被占用会自动从8719开始依次扫描,直至找到未被占用的端口
port: 8719
clientIp: 127.0.0.1
#这里是关键
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: ${spring.application.name}
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
management:
endpoint:
web:
exposure:
include: '*'
nacos的新增配置:
[
{
"resource":"/test/myexec",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false
}
]
配置说明: