说到流量服务控制,那么肯定有很多人都不太了解这个内容,因为如果对服务要求不是那么严格的情况下,基本是不会使用到这个东西的,但是,如果想要通过多个维度来保护服务和维持系统稳定性的话,那么就一定离不开Sentinel。
什么是 Sentinel
Sentinel是阿里巴巴公司开源的面向分布式环境的轻量级流量控制框架。
Sentinel 主要是用来做什么的
Sentinel是以流量为切入点,通过多个维度来保护服务和维持系统稳定性的工具。
主要功能:
- 流量控制
- 熔断降级
- 系统负载保护
我们来分别的看一下都是什么意思,首先这个流量控制,
什么是流量控制呢?
就比如说,我们的请求,堆积起来成批次的时候,就相当于是流量,当有大批的请求流量过来的时候,Sentinel就得起到一些作用了,它就相当于是一个调配器,将随机的请求变成顺序的请求,将不同格式的请求格式化为统一的格式的请求。
那么什么是熔断降级呢?
实际上熔断降级就是在调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积,然后为了避免这种情况,就有了熔断降级。
发生熔断降级时,系统这时候所处的状态可能为:
- 调用(响应)超时
- 异常比例升高
所以熔断降级会进行处理,通过并发线程数进行限制,还有就是通过响应时间对资源进行降级。
那么过载保护又体现在哪些方面呢?
其实主要就是体现在系统资源占用比例过高,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
为什么使用 Sentinel
我们来看看这个 Sentinel 都有哪些优点,为什么这么人都使用呢?
我们都知道这个 Sentinel 是阿里开源的,甚至在双十一大促的时候,也起到了关键性的作用。
比如其中的秒杀,集群流量控制,消息削峰填谷,所以第一个优点就出来了,
1.应用场景丰富。
如果你使用过 Sentinel ,那么一定登陆过 Sentinel 的后台,它的后台十分完善,服务流量的实时显示,集群汇总的运行情况,都是非常完美的,所以第二个优点也有了。
2.完善的实时监控
第三个优点,其实其他很多的工具都是有的,那就开源,那么我们就来看看这个 Sentinel 在 Windows 下是如何使用的。
Sentinel 控制台
毕竟我们刚才已经说了他有完善的实时监控了,而这个实时监控也能体现在我们的页面上,那么他就是控制台程序,我们直接来整一下。
1.下载 Windows 的安装包
Windows下的jar
了不起已经把jar包已经下载下来了,接下来我们看看如何启动,其实启动jar包的方式那我都不需要说,肯定都知道,但是启动 Sentinel 的 Jar 包也是需要有些参数的,比如如下需要你了解的参数。
- -Dserver.port:指定启动的端口,默认8080
- -Dproject.name:指定本服务的名称
- -Dcsp.sentinel.dashboard.server:指定sentinel控制台的地址,用于将自己注册进入实现监控自己
- -Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 "sentinel",默认值为 “sentinel”
- -Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 "123456",默认值为 "sentinel"
- -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟,需要注意的是,部署多台控制台时,session 默认不会在各实例之间共享,这一块需要自行改造。
了解这么多也不错了,然后我们来弄个比较简单的启动
我们直接用比较简单的命令来启动。
java -Dserver.port=9999 -Dcsp.sentinel.dashboard.server=localhost:9999 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
默认账号和密码都是 sentinel
我们直接登陆,然后看到的就是他的控制面板了。
我们看到了控制台,接下来我们就得去看看整合到项目中,是如何实现限流的。
Sentinel 整合入SpringBoot中
创建 SpringCloud的项目,了不起就不再说了,直接说怎么引入这个 Sentinel 吧。
依赖引入:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
其实往上还有很多博主说需要引入一些不如 actuator 的依赖,其实不需要,原因显而易见,这和个包肯定是包含这些依赖的,比如::
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>2.4.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<version>2.4.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.4.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
在 spring-cloud-starter-alibaba-sentinel中实际上已经都引入过了,所以不需要再单独的去引入依赖。
依赖引入了,接下来就得看看怎么配置这个配置文件
spring:
application:
name: xxxxx
cloud:
nacos:
config:
username: nacos
password: nacos
context-path: /nacos
server-addr: 127.0.0.1:8848
file-extension: yml
group: DEFAULT_GROUP
discovery:
username: nacos
password: nacos
server-addr: 127.0.0.1:8848
sentinel:
# sentinel看板的地址
transport:
dashboard: localhost:9999
# 开启对sentinel看板的饥饿式加载。sentinel默认是懒加载机制,只有访问过一次的资源才会被监控,通过关闭懒加载,在项目启动时就连接sentinel控制台
eager: true
了不起就截图了一些内容,主要看sentinel 的配置就可以,
当我们启动的时候,然后访问一下swagger的文档,
此时查看sentinel控制台,将会看见这个服务已经被监控了。
Sentinel 限流使用方法
Sentinel 可以简单分为 Sentinel 核心库和 Dashboard,核心库不依赖 Dashboard,但是结合 Dashboard 可以获得更好的效果。使用 Sentinel 来进行资源保护,主要分为几个步骤:
(1)定义资源:资源可以是程序中的任何内容,例如一个服务,服务里的方法,甚至是一段代码。
(2)定义规则:Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。
(3)检验规则是否生效
由于 Sentinel 中所有的规则都可以在动态地查询和修改,并且修改后立即生效,并且 Sentinel 中资源定义和规则的配置是分离的。因此在编码时,我们先把需要保护的资源定义好(埋点),之后便可以在需要的时候动态配置规则了。也可以理解为,只要有了资源,我们就能在任何时候灵活地定义各种规则。
实现方式有两种,第一种是通过硬编码的方式,但是这种方式很少有人使用,侵入性太高了呀,改代码还得改一堆东西,了不起就不说了,我们主要来说说这个使用注解的方式,这种方式方便而且还简单。
@SentinelResource注解方式(推荐)
我们先看看注解源码都写了啥?
package com.alibaba.csp.sentinel.annotation;
import com.alibaba.csp.sentinel.EntryType;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SentinelResource {
/**
* @return name of the Sentinel resource
*/
String value() default "";
/**
* @return the entry type (inbound or outbound), outbound by default
*/
EntryType entryType() default EntryType.OUT;
/**
* @return the classification (type) of the resource
* @since 1.7.0
*/
int resourceType() default 0;
/**
* @return name of the block exception function, empty by default
*/
String blockHandler() default "";
/**
* The {@code blockHandler} is located in the same class with the original method by default.
* However, if some methods share the same signature and intend to set the same block handler,
* then users can set the class where the block handler exists. Note that the block handler method
* must be static.
*
* @return the class where the block handler exists, should not provide more than one classes
*/
Class<?>[] blockHandlerClass() default {};
/**
* @return name of the fallback function, empty by default
*/
String fallback() default "";
/**
* The {@code defaultFallback} is used as the default universal fallback method.
* It should not accept any parameters, and the return type should be compatible
* with the original method.
*
* @return name of the default fallback method, empty by default
* @since 1.6.0
*/
String defaultFallback() default "";
/**
* The {@code fallback} is located in the same class with the original method by default.
* However, if some methods share the same signature and intend to set the same fallback,
* then users can set the class where the fallback function exists. Note that the shared fallback method
* must be static.
*
* @return the class where the fallback method is located (only single class)
* @since 1.6.0
*/
Class<?>[] fallbackClass() default {};
/**
* @return the list of exception classes to trace, {@link Throwable} by default
* @since 1.5.1
*/
Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class};
/**
* Indicates the exceptions to be ignored. Note that {@code exceptionsToTrace} should
* not appear with {@code exceptionsToIgnore} at the same time, or {@code exceptionsToIgnore}
* will be of higher precedence.
*
* @return the list of exception classes to ignore, empty by default
* @since 1.6.0
*/
Class<? extends Throwable>[] exceptionsToIgnore() default {};
}
- value:资源名称,必需项
- entryType:entry 类型,可选项(默认为 EntryType.OUT)
- blockHandler / blockHandlerClass:blockHandler 指定函数负责处理 BlockException 异常,可选项。blockHandler 函数默认需要和原方法在同一个类中,通过指定 blockHandlerClass 为对应类的 Class 对象,则可以指定其他类中的函数,但注意对应的函数必需为 static 函数,否则无法解析
- fallback /fallbackClass:fallback 指定的函数负责处理业务运行的异常,可选项,fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。
- defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑。defaultFallback 函数默认需要和原方法在同一个类中,通过指定 fallbackClass 为对应类的 Class 对象,则可以指定指定为其他类的函数,但注意对应的函数必需为 static 函数,否则无法解析。defaultFallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback和 defaultFallback,则只有 fallback会生效。
- exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
其中不常用的可以了解就可以了,你说呢?