<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
文档:
https://github.com/alibaba/Sentinel/wiki/控制台
1.查看机器列表以及健康情况:收集 Sentinel 客户端发送的⼼跳包,⽤于判机器是否在线。
2.监控 (单机和集群聚合)通过 Sentinel 客户端暴露的监控API,定期拉取并且聚合应⽤监控信息,最终可以实现秒级的实时监控。
3.规则管理和推送:统⼀管理推送规则。
4.鉴权:⽣产环境中鉴权⾮常重要。这⾥每个开发者需要根据⾃⼰的实际情况进⾏定制
//先进入jar包的文件夹
//启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本,
//-Dserver.port=8080 ⽤于指定 Sentinel 控制台端⼝为 8094
//默认⽤户名和密码都是 sentinel
java -Dserver.port=8094 -Dcsp.sentinel.dashboard.server=localhost:8094 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
如果没有权限
chmod 777 sentinel-dashboard-1.8.0.jar
http://localhost:8094/
账号密码都是Sentinel
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8094 (这个8094可以重复 因为是sentinel监听端口)
port: 8095(这个不能重复,不同模块不同的port)
client-ip: window本机的ip
接口上加@SentinelResource注解
举个例子
@SentinelResource("/same")
@RequestMapping("/same")
跑起来之后 postman调用接口 就能进行实时监控
原理是监控应⽤流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进⾏控制,以避免被瞬时的流量⾼峰冲垮,从⽽保障应⽤的⾼可⽤性。
这时候在簇点链路里面 流控
单机阈值2 说明一秒呢请求两次以上 第三次就会请求失败
…并发数控制⽤于保护业务线程池不被慢调⽤耗尽
…Sentinel 并发控制不负责创建和管理线程池,⽽是简单统计当前请求上下⽂的线程数⽬(正在执⾏的调⽤数⽬)
…如果超出阈值,新的请求会被⽴即拒绝,效果类似于信号量隔
离。并发数控制通常在调⽤端进⾏配置
流控规则会下发到微服务,微服务如果重启,则流控规则会消失可以持久化配置
延时 模拟多个线程
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
这时候设置线程数为1 浏览器多次请求就会请求失败
直接拒绝:默认的流量控制⽅式,当QPS超过任意规则的阈值后,新的请求就会被⽴即拒绝
Warm Up:冷启动/预热,如果系统在此之前⻓期处于空闲的状态,我们希望处理请求的数量是缓步的增多,经过预期的时间以后,到达系统处理请求个数的最⼤值
匀速排队:严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法,主要⽤于处理间隔性突发的流量,如消息队列,想象⼀下这样的场景,在某⼀秒有⼤量的请求到来,⽽接下来的⼏秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,⽽不是在第⼀秒直接拒绝多余的请求
选择以慢调⽤⽐例作为阈值,需要设置允许的慢调⽤ RT(即最⼤的响应时间),请求的响应时间⼤于该值则统计为慢调⽤
最大响应时间为100毫秒,超过就降级
比例阈值 比如十个线程里面有一个超过100毫秒就降级
熔断10秒
请求数如果只有10个 那就不会触发熔断 因为最小请求数为20
异常⽐例:当单位统计时⻓内请求数⽬⼤于设置的最⼩请求数⽬,并且异常的⽐例⼤于阈值,则接下来的熔断时⻓内请求会⾃动被熔断
异常数:当单位统计时⻓内的异常数⽬超过阈值之后会⾃动进⾏熔断
@Component
public class HBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
HashMap<String, Object> info = new HashMap<>();
if(e instanceof FlowException){
info.put("code",-1);
info.put("msg","限流异常");
}else if(e instanceof DegradeException){
info.put("code",-2);
info.put("msg","降级异常");
}else if(e instanceof ParamFlowException){
info.put("code",-3);
info.put("msg","热点参数异常");
}else if(e instanceof SystemBlockException){
info.put("code",-4);
info.put("msg","系统异常");
}else if(e instanceof AuthorityException){
info.put("code",-5);
info.put("msg","授权异常");
}
httpServletResponse.setStatus(200);
httpServletResponse.setHeader("content-type","application/json;charset=UTF-8");
httpServletResponse.getWriter().write(JSON.toJSONString(info));
}
}
依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibabasentinel</artifactId>
</dependency>
开启feign对Sentinel的支持
feign:
sentinel:
enabled: true
创建容错类,实现对于接口,实现如果调用feign的被调用方宕机,会把Fallback里的结果当错兜底数据返回回去,不然被调用方宕机后页面直接没数据了
public class VideoServiceFallback implements VideoService {
@Override
public Video findById(int videoId) {
Video video = new Video();
video.setTitle("这是Fallback里面的视频");
return video;
}
@FeignClient(name="class-video-service",fallback = VideoServiceFallback.class)
@Service
public interface VideoService {
@GetMapping(value = "/api/v1/video/find_by_id")
Video findById(@RequestParam("videoId") int videoId);
}
这时候调用controller的接口 并且把/api/v1/video/find_by_id的服务关掉 就能返回兜底数据