【alibaba-cloud】sentinel的使用

简介

Sentinel 是面向微服务的轻量级流量控制框架,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。代替了Hystrix。

Hystrix 的关注点在于以 隔离 和 熔断 为主的容错机制,超时或被熔断的调用将会快速失败,并可以提供 fallback 机制。

而 Sentinel 的侧重点在于:

  1. 多样化的流量控制 
  2. 熔断降级 
  3. 系统负载保护   
  4. 实时监控和控制台

【alibaba-cloud】sentinel的使用_第1张图片

安装包

安装包下载的网盘地址。

链接:https://pan.baidu.com/s/17mjnUvDBlWdCgNYIIxkv0w 
提取码:iws1

官网:https://github.com/alibaba/Sentinel/releases

使用

1.启动jar包

java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar sentinel-dashboard-1.6.3.jar

 在浏览器输入http://localhost:8718/,出现以下的界面就是成功了,账号和密码默认都是sentinel。

【alibaba-cloud】sentinel的使用_第2张图片

2.搭建工程

搭建的工程我们用之前搭建的,搭建的博客如下

客户端和服务端的搭建:https://blog.csdn.net/wangyunzhao007/article/details/106895672

网关的搭建:https://blog.csdn.net/wangyunzhao007/article/details/106895545

在搭建完以上两个博客后我们还要对order-service开始改造,

在order-service中加入依赖

    
    
        org.springframework.cloud
        spring-cloud-alibaba-sentinel
        0.2.2.RELEASE
    
    
        org.springframework.boot
        spring-boot-starter-actuator
    
    
    
        com.alibaba.csp
        sentinel-datasource-nacos
        1.5.2
    

然后添加一个controller类

package com.order.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SentinelServiceImpl {

    //热点词
    private static final String SEKILL_RULE = "seckill";

    /**
     * 被限流后返回的提示
     *
     * @param e
     * @return
     */
    public String getOrderQpsException(BlockException e) {
        e.printStackTrace();
        return "该接口已经被限流啦!";
    }

    /**
     * 根据qps限流
     * @return
     */
    @SentinelResource(value = "getOrderDashboard", blockHandler = "getOrderQpsException")
    @RequestMapping("/getOrderDashboard")
    public String getOrderDashboard() {
        return "getOrderDashboard";
    }

    /**
     * 根据线程数限流
     * @return
     */
    @SentinelResource(value = "getOrderThrad", blockHandler = "getOrderQpsException")
    @RequestMapping("/getOrderThrad")
    public String getOrderThrad() {
        System.out.println(Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (Exception e) {

        }
        return "getOrderThrad";
    }




    @SentinelResource(value = "getOrderSentinel", blockHandler = "getOrderQpsException")
    @RequestMapping("/getOrderSentinel")
    public String getOrderSentinel() {
        return "getOrderSentinel";

    }
    /*--------------------------------------------服务降级-------------------------------------------------*/

    /**
     * 平均响应时间
     * @return
     */
    @SentinelResource(value = "getOrderDowngradeRtType", fallback = "getOrderDowngradeRtTypeFallback")
    @RequestMapping("/getOrderDowngradeRtType")
    public String getOrderDowngradeRtType() {
        try {
            Thread.sleep(300);
        } catch (Exception e) {
        }
        return "getOrderDowngradeRtType";
    }

    public String getOrderDowngradeRtTypeFallback() {
        return "服务降级啦,当前服务器请求次数过多,请稍后重试!";
    }


    /**
     * 异常比例
     * @param age
     * @return
     */
    @SentinelResource(value = "getOrderDowngradeErrorType", fallback = "getOrderDowngradeErrorTypeFallback")
    @RequestMapping("/getOrderDowngradeErrorType")
    public String getOrderDowngradeErrorType(int age) {
        int j = 1 / age;
        return "正常执行我们的业务逻辑";
    }

    public String getOrderDowngradeErrorTypeFallback(int age) {
        return "服务降级啦,当前服务器请求次数过多,请稍后重试!";
    }
    /*--------------------------------------------热点词限流-------------------------------------------------*/

    /**
     * 热点词限流
     */
    @RequestMapping("/seckill")
    @SentinelResource(value = SEKILL_RULE, fallback = "seckillFallback", blockHandler = "seckillBlockHandler")
    public String seckill(Long userId, Long orderId) {
        return "秒杀成功";
    }

}

更改以后的配置文件,增加了sentinel的配置

spring:
  application:
    ###服务名称
    name: order-sevice
  cloud:
    nacos:
      discovery:
        ###nacos注册地址
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8718
      eager: true

server:
  port: 8083

然后我们启动项目,sentinel的操作台,我们可以看到我们刚刚配置的服务。

【alibaba-cloud】sentinel的使用_第3张图片

搭建好的项目代码链接:等待上传,正在整理。

3.限流

1.QPS

我们在搭建完成并启动后,需要在sentinel中添加限流规则。资源名为:getOrderDashboard,阈值我们写2

【alibaba-cloud】sentinel的使用_第4张图片

然后我们在浏览器输入 http://localhost:8083/getOrderDashboard,一秒内多刷新几次,超过阈值2,就会出现限流;

2.线程数

线程是同样的道理,选择线程数,代表一秒内有可以处理多少线程,超出就会限流。阈值为2,代表一秒超过两个线程,就会限流。新增限流规则:

【alibaba-cloud】sentinel的使用_第5张图片

在浏览器输入http://localhost:8083/getOrderThrad,我看可以看到调用成功。

一秒内快速刷新几次页面:由于我设置了接口会睡眠一秒,故一秒内多刷新几次,就能模拟多个线程的情况。超过阈值后限流。

当我们停止服务后,发现sentinel操作台限流规则没有了,只要重新启动就会消失,所以我们应该将限流规则持久化,我们选择持久化到nacos

3.sentinel限流规则持久化到nacos

首先我们在nacos添加配置

【alibaba-cloud】sentinel的使用_第6张图片

[
    {
        "resource": "/ getOrderSentinel",
        "limitApp": "default",
        "grade": 1,
        "count": 5,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]
  • resource:资源名,即限流规则的作用对象
  • limitApp:流控针对的调用来源,若为 default 则不区分调用来源
  • grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
  • count:限流阈值
  • strategy:调用关系限流策略
  • controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
  • clusterMode:是否为集群模式

还需要添加依赖


    com.alibaba.csp
    sentinel-datasource-nacos
    1.5.2

 配置文件修改为

spring:
  application:
    ###服务名称
    name: order-sevice
  cloud:
    nacos:
      discovery:
        ###nacos注册地址
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8718
      eager: true
      datasource:
        ds:
          nacos:
            ### nacos连接地址
            server-addr: localhost:8848
            ## nacos连接的分组
            group-id: DEFAULT_GROUP
            ###路由存储规则
            rule-type: flow
            ### 读取配置文件的 data-id
            data-id: order-sentinel
            ###  读取培训文件类型为json
            data-type: json

server:
  port: 8083

然后重启服务,我们不用重新添加了,可以看到我们在nacos中写的规则。 

 【alibaba-cloud】sentinel的使用_第7张图片

4.熔断和降级

降级策略

 

1.平均响应时间(DEGRADE_GRADE_RT) 

当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。

在sentinel操作台中添加降级规则:

【alibaba-cloud】sentinel的使用_第8张图片

 【alibaba-cloud】sentinel的使用_第9张图片

在输入http://localhost:8083/getOrderDowngradeRtType 后,我们看到调用成功!

我们在一秒内多刷新几次,当平均响应时间超出时候,就会服务降级。

2.异常比例(DEGRADE_GRADE_EXCEPTION_RATIO)

当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

【alibaba-cloud】sentinel的使用_第10张图片

然后调用http://localhost:8083/getOrderDowngradeErrorType?age=0,因为0/0是错误的,所以出现异响比率。

【alibaba-cloud】sentinel的使用_第11张图片

多刷新几次。就会出现服务降级

3.异常数 (DEGRADE_GRADE_EXCEPTION_COUNT)

当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

 

fallback与blockHandler的区别

fallback是服务熔断或者业务逻辑出现异常执行的方法(1.6版本以上)

blockHandler 限流出现错误执行的方法。

5.热点词限流

这里热点词限流的代码

【alibaba-cloud】sentinel的使用_第12张图片

然后我们配置热点规则

【alibaba-cloud】sentinel的使用_第13张图片

然后输入http://localhost:8083/seckill?userId=1&orderId=2,多刷新几次后,会出现限流。

【alibaba-cloud】sentinel的使用_第14张图片

但是很怪哦,既没有走blockHandler,也没有走fallback。

所以热点词的处理不是这样处理的,所以我们需要添加全局捕获异常捕获修改限流出现错误。(没有做持久化,重启后,限流和降级规则都是消失,都需要重新添加。

@RestControllerAdvice
public class InterfaceExceptionHandler {
    @ResponseBody
    @ExceptionHandler(ParamFlowException.class)
    public String businessInterfaceException(ParamFlowException e) {
        return "您当前访问的频率过高,请稍后重试!";
    }
}

重新添加配置 

 【alibaba-cloud】sentinel的使用_第15张图片

 然后可以看到处理结果:

当我们输入下面的地址时候,因为第二个参数为888,使我们的例外项,其他的参数都是超过一秒两次后限流,但是888是超过3次后限流。

http://localhost:8083/seckill?userId=1&orderId=888

本章代码资源:

https://download.csdn.net/download/wangyunzhao007/12550683

你可能感兴趣的:(Spring,Cloud学习)