为什么出现了Sentinel
当服务器的流量暴涨时,因为性能的问题,可能会出现页面无法显示,app反应慢,功能无法正常进行运转,功能无法正常运转的时候,严重会导致整个网站的崩溃,因此出现了,当负载过高的时候,我们可以采用,降级、熔断、限流,三种方式来保护系统,这促生了Sentinel管理流量的中间件
Sentinel
用到的设计模式:责任链模式、代理模式、观察者模式、
啥是SENTINEL:分布式系统的流量卫兵
是阿里开源的一套用于服务容错的综合解决方案,它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
核心(两部分)
1.JAVA(核心库)能够运行于所有Java运行时环境,同时对Bubbo/Spring Cloud等框架也有较好的支持
2.控制台:基于springBoot开发 打包后直接运行
咋让他跑起来
下载jar包 --- 在jar包的对应目录 cmd ---- 运行以下命令
java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
- 最简单的方法是在IDEA 中启动,
- 注意:在IDEA 中添加时,地址写的是要具体到JAVA的命令,其次,命令不需要写java
咋访问 :默认的端口号8180 直接地址栏 localhost:8180即可 默认用户和密码都是sentinel
咋让其对服务实现限流
限流的目的防止恶意请求流量、恶意攻击,或者防止流量超过系统峰值
第一步:添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
第二步:打开服务方提供的bootstrap.yml,添加sentinel(使用Sentinel时,要把资源目录下的appactional.yml,转换为bootstrap.yml)
添加层级关系
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8180 # 指定sentinel控制台地址。可修改
第三步:运行你的服务,并且对你设定好的服务进行访问
第四步:刷新控制台网页!sentinel控制台,实时监控信息
第五步:设置限流股则 点击流控 --- 设置阈值类型、单机阈值
类型QPS 表示每秒请求数 单机阈值 表示对应类型每秒允许的请求次数
流控模式
三种:直接,关联,链路
流控的默认形式就是 直接→快速失败
关联模式:要设定关联的服务,当关联的服务达到一定的访问量时,就限流自己
1与2绑定一起,2的业务更重要,1不那么重要
链路模式:1.7.2以后,所有URL自动聚合在sentinel_spring_web_context内
需要在springboot的配置文件中添加,这样就可以实现单独对指定链路的限流
解决限流后的前端显示的内容
第一步:定义一个类在类中写好方法类中传入的正是限流异常BlockException ex
ackage com.jt.provider.service;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ResourceBlockHandler {
/**
* 限流后的异常处理方法,应用于@SentinelResource注解中,
* 此方法在编写时有如下几个要求:
* 1)方法修饰符为public
* 2)必须为static方法
* 3)返回值类型与@SentinelResource注解描述的方法相同
* 4)参数类型为BlockException
* 5)方法名自己定义
* @param ex
* @return
*/
public static String doHandle(BlockException ex){
log.error("block exception {}", ex.getMessage());
return "访问太频繁了,稍等片刻再访问";
}
}
sentinel:
web-context-unify: false 用于关闭url path聚合
第二步: 修改@SentinelResource注解中的属性定义,例如:
@SentinelResource(value="doGetResource",
blockHandlerClass = ResourceBlockHandler.class, //自己定义好的类
blockHandler = "doHandle") //具体施行方法的id
public String doGetResource(){
return "do get resource";
}
第三步: 在controller方法中,调用@Sentinel注解描述的方法,例如:
/**
* 演示链路限流
* @return
*/
@GetMapping("/sentinel03")
public String doSentinel03(){
return resourceService.doGetResource();
//return "sentinel 03 test";
}