1.什么是Sentinel

Sentinel 是由阿里巴巴中间件团队开发的开源项目,是一种面向分布式微服务架构的轻量级高可用流量控制组件
Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度帮助用户保护服务的稳定性。
从功能上来说,Sentinel 与 Spring Cloud Netfilx Hystrix 类似,但 Sentinel 要比 Hystrix 更加强大,例如 Sentinel 提供了流量控制功能、比 Hystrix 更加完善的实时监控功能等等。

2.Sentinel的优势

  1. 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的“双十一”大促流量的核心场景,例如秒杀(将突发流量控制在系统可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等。
  2. 完备的实时监控:Sentinel 提供了实时监控功能。用户可以在控制台中看到接入应用的单台机器的秒级数据,甚至是 500 台以下规模集群的汇总运行情况。
  3. 广泛的开源生态:Sentinel 提供了开箱即用的与其它开源框架或库(例如 Spring Cloud、Apache Dubbo、gRPC、Quarkus)的整合模块。我们只要在项目中引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。此外,Sentinel 还提供 Java、Go 以及 C++ 等多语言的原生实现。
  4. 完善的 SPI 扩展机制:Sentinel 提供简单易、完善的 SPI 扩展接口,我们可以通过实现这些扩展接口快速地定制逻辑,例如定制规则管理、适配动态数据源等。

    3.Sentinel组成

  5. Sentinel 核心库(客户端):Sentinel 的核心库不依赖任何框架或库,能够运行于 Java 8 及以上的版本的运行时环境中,同时对 Spring Cloud、Dubbo 等微服务框架提供了很好的支持。

  6. Sentinel 控制台(Dashboard):Sentinel 提供的一个轻量级的开源控制台,它为用户提供了机器自发现、簇点链路自发现、监控、规则配置等功能。

Sentinel 核心库不依赖 Sentinel Dashboard,但两者结合使用可以有效的提高效率,让 Sentinel 发挥它最大的作用。

4.Sentinel核心概念

概念 描述
资源 资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如由应用程序提供的服务或者是服务里的方法,甚至可以是一段代码。
我们可以通过 Sentinel 提供的 API 来定义一个资源,使其能够被 Sentinel 保护起来。通常情况下,我们可以使用方法名、URL 甚至是服务名来作为资源名来描述某个资源
规则 围绕资源而设定的规则。Sentinel 支持流量控制、熔断降级、系统保护、来源访问控制和热点参数等多种规则,所有这些规则都可以动态实时调整。

5.windows下Sentinel控制台搭建流程

1.下载jar包

下载地址:点击这里
如图,可下载编译好的jar包或下载源码自己编译。建议下载jar包
image.png

2.启动jar包

启动命令示例(可指定端口):

  1. # 自定义端口命令
  2. java -Dserver.port=2222 -jar sentinel-dashboard-1.8.1.jar
  3. # 自定义端口且将控制台作为服务注册到控制台命令
  4. java -Dserver.port=2222 -Dcsp.sentinel.dashboard.server=localhost:2222 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar

启动成功后如图:
image.png

3.登录控制台

登录地址:http://ip:启动端口
默认用户名密码:sentinel
image.png
登录成功如图:
image.png

6.linux下Sentine控制台搭建流程

1.新建文件夹

  1. mkdir /data/sentinel
  2. cd /data/sentinel

    2.下载jar包

    下载地址:点击这里
    如图,复制链接地址即可
    image.png
    下载命令示例:wget https://github.com/alibaba/Sentinel/releases/download/1.8.4/sentinel-dashboard-1.8.4.jar

    3.通过supervisor管理sentinel进程

  3. touch /etc/supervisord.d/sentinel-dash.ini

  4. vim /etc/supervisord.d/sentinel-dash.ini
  5. 输入以下内容

    1. [program:sentinel-dash]
    2. directory=/data/sentinel
    3. command=java -Dserver.port=2222 -jar /data/sentinel/sentinel-dashboard.jar
    4. autorestart=true
    5. redirect_stderr=true
    6. stdout_logfile=/data/sentinel/sentinel-dashboard.log
  6. supervisorctl update

  7. supervisorctl status

如图,进程启动成功
image.png

4.开通控制台端口

端口:启动时指定的端口,默认8080
作用:sentinel控制台对外暴露端口,开通后才可访问控制台页面
因为使用的是阿里云,所以这边直接添加安全组即可
image.png

5.开通Sentinel核心库(客户端)端口

端口:开通8719到8799端口(没有固定限制,但是必须从8719开始)
作用:sentinel控制台连接sentinel客户端并监控所需端口
因为使用的是阿里云,所以这边直接添加安全组即可
image.png

6.确保核心库与控制台之间连接正常

7.Sentinel核心库(客户端)整合SpringCloud

引入依赖

  1. <!--Sentinel 依赖-->
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  5. </dependency>

编写配置文件

  1. management:
  2. endpoints:
  3. web:
  4. exposure:
  5. include: '*' #暴露所有端点
  6. server:
  7. port: 1001 #服务端口
  8. spring:
  9. application:
  10. name: sentinel-service #服务名
  11. cloud:
  12. nacos:
  13. discovery:
  14. server-addr: 8.142.132.135:8848
  15. sentinel:
  16. transport:
  17. dashboard: localhost:2222 #Sentinel控制台地址
  18. port: 8719 #Sentine客户端暴露给控制台的端口。默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口

访问控制台

此时依旧为空
image.png因为Sentinel为懒加载模式,因此需要对应的接口被触发以后才能被控制台发现并监控
此时我们触发该服务的任意接口
服务控制台出现如下日志,说明Sentinel接入成功
image.png
再次刷新访问控制台,服务接入成功,已被控制台监控并管理
image.png

开启饿汉式加载

有时候需要服务启动后直接就接入到控制台,此时需要在配置文件中通过将eager属性设置为true开启饿汉式加载

  1. management:
  2. endpoints:
  3. web:
  4. exposure:
  5. include: '*' #暴露所有端点
  6. server:
  7. port: 1001 #服务端口
  8. spring:
  9. application:
  10. name: sentinel-service #服务名
  11. cloud:
  12. nacos:
  13. discovery:
  14. server-addr: 8.142.132.135:8848
  15. sentinel:
  16. eager: true #Sentinel开启饿汉式加载
  17. transport:
  18. dashboard: localhost:2222 #Sentinel控制台地址
  19. port: 8719 #Sentine客户端暴露给控制台的端口。默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口

启动服务并访问控制台
服务启动后无需触发API访问即可监测到该服务
image.png

8.Sentinel核心注解@SentinelResource

@SentinelResource 注解是 Sentinel 提供的最重要的注解之一,它还包含了多个属性

value

作用:用于指定资源的名称
是否必填:是
使用要求:符合对应的命名规则且语义明确即可

entryType

作用:流量类型
是否必填:否(默认为EntryType.OUT,同时还有Entry.IN)
使用要求:EntryType是一个枚举类型,包括了IN/OUT两个值。可以理解为发起请求还是接收请求。当接收到别的服务或者前端发来的请求(服务提供者),那么 entryType 为 IN;当向其他服务发起请求时(服务调用者),那么 entryType 就为 OUT

blockHandler

作用:服务限流或熔断后会抛出 BlockException 异常以及其子类异常,而 blockHandler 则是用来指定一个函数来处理 BlockException 异常的。简单点说,该属性用于指定捕获blockException或其子类异常,优先级较高。
是否必填:否
使用要求

  1. blockHandler 函数修饰符必须是 public;
  2. 返回类型必须与原方法一致;
  3. 参数类型必须与原方法一致并且最后加一个额外的参数,类型为 BlockException;
  4. blockHandler 函数默认必须与原方法在同一个类中,若希望使用其他类的函数,则可以指定 blockHandler 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

    blockHandlerClass

    作用:若 blockHandler 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。
    是否必填:否
    使用要求

  5. 不能单独使用,必须与 blockHandler 属性配合使用;

  6. 该属性指定的类中的 blockHandler 函数必须为 static 函数,否则无法解析

    fallback

    作用:用于在抛出异常(包括 BlockException)时,提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。该属性用于捕获所有异常,如果系统未声明blockHandler,那么会有fallback捕获BlockException以及其子类异常。优先级低于blockHandler。
    是否必填:
    使用要求:

  7. 返回值类型必须与原函数一致;

  8. 方法参数列表必须与原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;
  9. fallback 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

    fallbackClass

    作用:若 fallback 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。
    是否必填:
    使用要求:

  10. 不能单独使用,必须与 fallback 或 defaultFallback 属性配合使用;

  11. 该属性指定的类中的 fallback 函数必须为 static 函数,否则无法解析。

    defaultFallback

    作用:默认的 fallback 函数名称,通常用于通用的 fallback 逻辑(可以用于很多服务或方法)。
    默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
    是否必填:
    使用要求:

  12. 返回值类型必须与原函数一致;

  13. 方法参数列表必须为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;
  14. defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

    exceptionsToIgnore

    作用:用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
    是否必填:
    使用要求:
    注:在 Sentinel 1.6.0 之前,fallback 函数只针对降级异常(DegradeException)进行处理,不能处理业务异常。

    9.@SentinelResource 坑点

    @SentinelResource 注解不单单用于controller的接口流控。同时也可以用于方法上面。如果看过实现方式代码。可以知道他底层是基于cglib动态代理实现的。进行切面处理。注意点:

  15. 不能修饰在接口上面。只能修饰在实现类的方法上

  16. 不能修饰在静态的方法上面。
  17. 同一个bean方法A调用方法B,假设方法A和B都进行了注解。B方法注解失效,