这篇文章,主要介绍微服务组件之Sentinel控制台的使用(Sentinel Dashboard)。
目录
一、Sentinel控制台
1.1、下载Dashboard控制台
1.2、搭建测试工程
(1)引入依赖
(2)添加配置信息
(3)运行测试
1.3、实时监控
1.4、簇点监控
1.5、流控规则
(1)QPS流控规则
(2)并发线程数
(3)直连流控模式
(4)关联流控模式
(5)链路流控模式
(6)快速失败(流控效果)
(7)Warm Up(流控效果)
(8)排队等待(流控效果)
1.6、熔断降级规则
(1)慢调用比例
(2)异常比例
(3)异常数
1.7、热点规则
1.8、统一异常处理(BlockException)
一、Sentinel控制台
1.1、下载Dashboard控制台
Sentinel提供了一个Dashboard控制台,通过控制台也可以实现服务熔断、服务降级、流量控制等规则的配置,并且这种可视化界面的配置方式更加的友好,不需要编写任何Java代码,可能这也是Sentinel的强大之处吧。
首先需要去下载Sentinel Dashboard对应的应用程序Jar包【Sentinel控制台下载】,下载完成之后,直接打开CMD窗口,执行【javar -jar】启动应用即可。
启动成功之后,打开浏览器访问【http://localhost:8080/】地址,第一次访问需要先登录,登录的用户名和密码都是【sentinel】。
登录成功之后,就可以进入到控制台首页面。
注意:第一次访问Sentinel控制台的时候,由于还没有访问过任何的微服务应用,所以这个时候就没有相关的微服务监控信息。
1.2、搭建测试工程
这里为了演示Sentinel控制台的使用,需要搭建一个测试工程,测试工程中,需要指定连接的Sentinel控制台的服务地址,这样dashboard控制台中才能监听到微服务的信息。
(1)引入依赖
<!-- 引入 web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 sentinel 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
(2)添加配置信息
在application.yml配置文件中,添加sentinel的配置信息。
server:
port: 8899
spring:
application:
name: alibaba-sentinel-demo
# 配置 sentinel 控制台
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # 指定 sentinel 控制台服务 的地址
(3)运行测试
启动工程,然后随便访问一个接口,刷新dashboard控制台,此时就可以看见对应的微服务监控列表了。
到此,Sentinel控制台环境就搭建好了。
1.3、实时监控
实时监控:可以看到微服务中接口的调用情况。
1.4、簇点监控
簇点监控:展示当前微服务中,所有可用的资源,可以对这些资源进行熔断、降级、流控的相关配置,默认是将controller控制层中的接口作为资源显示出来。
1.5、流控规则
流控规则:对相关的资源设置流量控制规则,一般在高并发流量的场景里面,为了降低系统宕机情况,就会限制访问流量来提高系统的稳定性。哪些场景中,需要使用流量控制呢???
- 秒杀、下单、订单回流、消息型场景、API网关限流等情况。
(1)QPS流控规则
- QPS流控规则:限制每秒钟访问的请求数量。
访问demo01接口,当1秒钟超过2个请求时候,超过的请求将返回错误信息。
当然,也可以自己在代码中通过【@SentinelResource】注解,指定流控、降级之后的回调方法。
(2)并发线程数
- 并发线程数规则:当请求达到设置的最大线程数时候,在这些线程处理响应结束之前,如果此时还有线程到达,那么这个线程就会被流控。
打开两个浏览器,同时访问【demo03】接口(注意:这个接口中写了暂停3秒的逻辑),此时第二个访问的会出现流控。
(3)直连流控模式
直流流控模式:直接对添加流控的资源进行流量限制,默认就是采用这种限流模式。
(4)关联流控模式
关联流控模式:两个资源之间存在关联关系,假设A资源和B资源存在关联关系,对A资源进行流控规则,关联了B资源,那么此时如果A资源满足流控规则后,就会限流B资源,这就是关联流控模式。
- 这里模拟一下【关联流控模式】,首先由两个资源:【demo04】和【demo05】,给【demo04】添加流控规则,并且关联【demo05】资源。
- 使用jemeter访问【demo05】资源,访问的过程中,浏览器单独访问【demo04】资源,此时【demo04】资源会发生流控。
打开jemeter,模拟大量请求访问【demo05】接口,之后浏览器访问【demo04】接口,此时可以发现【demo04】发生了流控。
注意:关联流控模式下,只有关联资源才会触发目标资源的流控规则。
(5)链路流控模式
链路流控模式:根据接口的调用链路来实现流量控制,假设:A资源被B、C两个资源调用,也就是存在两个链路:B-->A、C-->A;那么就可以采用链路流控模式,对【B-->A】调用链路进行流控限制。
- 这里采用【demo06】、【demo07】、【demo】三个资源,其中【demo06】和【demo07】都会调用【demo】资源。
- 在sentinel控制台中,给【demo】资源添加流控规则,入口资源设置成【demo06】。
- 这个时候,就会对【demo06】进行限流控制。
打开浏览器,多次刷新页面访问【demo06】接口,此时会触发流控规则,而多次访问【demo07】接口不会触发流控规则。
注意:sentinel默认是不会维护调用链路的,需要我们自己在【application.yml】配置文件中配置。
spring:
# 配置 sentinel 控制台
cloud:
sentinel:
# 让 sentinel 维护调用链路树
web-context-unify: false
(6)快速失败(流控效果)
快速失败:当发生流控的时候,直接快速返回失败信息。
(7)Warm Up(流控效果)
Warm Up是【预热流控】的一种机制,所谓的预热流控,是指:当大量请求到达时候,假设一开始只处理3个请求,其他请求全部失败,之后逐渐增加处理更多的请求,例如:3个、6个、10个依次递增。sentinel默认的冷加载因子是3,它会根据【threshold / 3】开始,经过预热之后,逐渐达到阈值threshold。
使用jemeter访问【demo02】接口,查看监控图如下所示。
预热流控一般适用于积分流量场景下,什么是积分流量呢???积分流量是指:在某一段时间内可能出现大量的请求,但是过了那段时间,请求有变得平稳了,这种场景下就适用于预热流控。
(8)排队等待(流控效果)
排队等待:请求在达到设定的阈值时候,多余的请求会在指定的时间里面排队等待被处理,如果在指定时间里面,还没有被执行,那就直接失败。
使用jemeter每隔5秒钟发起10个请求访问【demo02】接口,运行结束之后,查看监控界面。
从上图中就可以看出,使用【排队等待】方式就已经能够很好的解决多余请求的处理问题,而不会出现快速失败的情况。为了验证排队等待的效果,你可以设置一个快速失败的方式,再次测试接口,查看监控界面。
从上图可以看到,快速失败方式下,会出现5个接口调用成功,5个接口调用失败,并且会有一个5秒钟的时间间隔(自己设置的时间间隔),排队等待就是利用这个时间间隔,处理处于等待中的请求,从而实现流控。
1.6、熔断降级规则
熔断降级规则有三种,分别是:慢调用比例、异常比例、异常数。当触发熔断之后,不会去调用微服务接口,是否直接返回快速失败。
(1)慢调用比例
慢调用比例:请求的响应时长超过给定的RT,并且满足【最小请求数】中满调用的占比达到阈值,则触发熔断规则。
打开jemeter,访问【demo03】接口,此时会出发熔断规则。
(2)异常比例
异常比例:在指定的请求数量里面,出现异常的请求达到指定比例,则触发熔断规则。
接口【exception】模拟抛出异常即可,然后使用jemeter调用测试。
(3)异常数
异常数:在最小请求数里面,出现异常的次数满足阈值,则发生熔断。
1.7、热点规则
热点规则:是针对接口请求中的热点参数进行流量控制,什么是热点参数呢???比如:一个查询接口中,根据商品名称查询,有:【手机】、【电脑】,假设用户大部分都查询【手机】,所以【手机】就相当于是一个热点参数,那就可以对针对这个查询参数的接口,进行流量控制。注意:热点参数规则,必须是使用【@SentinelResource】注解定义的资源。
- 编写测试方法。
@SentinelResource(value = "/api/sentinel/dashboard/parameter", blockHandler = "blockMethod")
@GetMapping("/parameter")
public String parameter(@RequestParam("id") String id, @RequestParam("name") String name) {
System.out.println("parameter接口调用成功.id=" + id + ", name=" + name);
return "parameter接口调用成功.id=" + id + ", name=" + name;
}
public String blockMethod(String id, String name, BlockException e) {
return "【" + name + "】触发热点参数流控规则";
}
- 配置热点参数规则。
- 浏览器访问【localhost:8899/api/sentinel/dashboard/parameter?id=1&name=手机】,多次刷新,此时就会触发热点参数流控规则。
以上就是热点参数规则的配置。
1.8、统一异常处理(BlockException)
自定义BlockException异常处理,可以针对不同的异常情况,响应不同的结果,当然你也可以不使用统一的异常处理,那就是需要在每一个方法中使用【@SentinelResource】注解定义异常处理方法。
package com.gitcode.demo.exception;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
/**
* @version 1.0.0
* @Date: 2023/4/25 20:32
* @Copyright (C) ZhuYouBin
* @Description: 统一异常处理【BlockException】
*/
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
// TODO 在这里就可以自定义返回响应数据
String msg = "";
if (e instanceof FlowException) {
msg = "流控异常";
} else if (e instanceof DegradeException) {
msg = "服务降级异常";
} else if (e instanceof ParamFlowException) {
msg = "热点参数流控异常";
} else if (e instanceof SystemBlockException) {
msg = "触发系统保护规则异常";
} else if (e instanceof AuthorityException) {
msg = "授权规则不通过异常";
}
// 响应结果
response.setStatus(500);
response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
// 返回JSON数据
new ObjectMapper().writeValue(response.getWriter(), msg);
}
}
到此,Sentinel控制台配置相关规则就介绍完啦。
综上,这篇文章结束了,主要介绍微服务组件之Sentinel控制台的使用(Sentinel Dashboard)。