sentinel的官方名称叫分布式系统的流量防卫兵。Sentinel 以流量R为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。在Spring Cloud项目中最开始我们使用的是Hystrix,目前已停止更新了。现在Spring Cloud官方推荐的是rensilience4j。当然还有我们今天学习的sentinel。
Sentinel 具有以下特征:
这里我们直接下载jar包即可,下载后通过命令行启动:
java -jar sentinel-dashboard-1.7.2.jar启动成功后,我们浏览器访问127.0.0.1:8080,出现如下界面。
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>server:
  port: 7003
spring:
  application:
    name: sentinel-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080@SpringBootApplication
public class SentinelApplication {
    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication.class, args);
    }
}
@RestController
class TestController{
    @GetMapping("/test")
    public String test(){
        return "hello! sentinel!";
    }
}我们请求几次这个接口后,打开sentinel控制台,就可以实时监控到这个sentinel-provider服务接口调用情况了。
我们这里做一个简单的规则配置:
意思就是:该接口每秒最多允许进入两个请求。
点击新增后,在流控规则里发现了一条规则:
现在,我们继续请求3次这个接口。第三次响应的内容如下:
Blocked by Sentinel (flow limiting)我们打开控制台发现拒绝了一条请求。
不管是限流还是降级,它都是按照某种规则进行的,下面具体介绍一下sentinel支持的几种规则。
流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时
对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
资源名:唯一名称,默认是请求路径,可自定义
针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制
阈值类型/单机阈值:
降级规则就是当满足什么条件时,对服务降级——即将请求转发到另外接口上,这个接口与业务无关,只是为了保证系统的完整性。
热点规则允许将规则具体到参数上。
我们用个例子来看看效果。
@GetMapping("/myTest")
@SentinelResource("test3")
public String test123(String name,String age){
    return  name + "----"+ age;
}结果显示,第一个参数被限流了,而第二个参数正常。
系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 、CPU使用率和线程数五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量 (进入应用的流量) 生效。
很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过:
流控应用:sentinel提供了RequestOriginParser来处理接口来源。
我们运行abc来源的请求访问/test接口。
@Component
class requestOrigin implements RequestOriginParser{
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String server = httpServletRequest.getParameter("server");
        return server;
    }
}我们请求127.0.0.1:7003/test?server=abc 和  127.0.0.1:7003/test?server=ab来分别看看效果。
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。
主要参数有以下几个
属性  | 作用  | 
|---|---|
value  | 资源名称  | 
entryType  | entry类型,标记流量的方向,取值IN/OUT,默认是OUT  | 
blockHandler  | 处理BlockException的函数名称,函数要求:1. 必须是 public;2.返回类型 参数与原方法一致;3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置blockHandlerClass ,并指定blockHandlerClass里面的方法。  | 
blockHandlerClass  | 存放blockHandler的类,对应的处理函数必须static修饰。  | 
fallback  | 1. 返回类型与原方法一致;2. 参数类型需要和原方法相匹配;3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置fallbackClass  | 
fallbackClass  | 存放fallback的类。对应的处理函数必须static修饰。  | 
defaultFallback  | 若同时配置了 fallback 和 defaultFallback,以fallback为准。  | 
exceptionsToIgnore  | 指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。  | 
exceptionsToTrace  | 需要trace的异常  | 
@sentinelResource可结合blockHandler用于限流处理,结合fallback用于降级处理。具体规则可通过sentinel控制台配置,具体我就不演示了,在下一章内容中,我会分别演示限流和降级的应用。
public class MySentinelResource {
    @SentinelResource(value="message",blockHandler="blockHandler",fallback="fallback")
    public String message(String str){
        if(StringUtils.isBlank(str)){
            throw new RuntimeException();
        }
        return str;
    }
    /**
     * 限流处理
     * @param str
     * @param ex
     * @return
     */
    public String blockHandler(String str, BlockedException ex){
        return str + "--"+ ex;
    }
    /**
     * 降级处理
     * @param str
     * @return
     */
    public String fallback(String str){
        return null;
    }
}