Skip to content
🔴🟠🟡🟢🔵🟣🟤⚫⚪

spring-cloud-alibaba-demo

七、整合sentinel 流量卫兵

sentinel是面向分布式服务框架的轻量级流量控制框架,主要以流量为切入点,从流量控制,熔断降级,系统负载保护等多个维度来维护系统的稳定性.

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

下载编译好的后台管理系统包:

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

这里使用的是 1.8.1 版本号:

sentinel安装包

sentinel-dashboard-1.8.1.jar

启动命令:

java
# 注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
# 其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080
# 从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。
# 可以参考 鉴权模块文档 配置用户名和密码。
# 启动成功后的后台地址 http://127.0.0.1:8080/

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar

启动后台jar包后,访问http://127.0.0.1:8080/ 用户名和密码都是sentinel

项目中添加maven依赖

java
<!--sentinel流量卫兵相当于 Hystrix-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  </dependency>

项目中添加sentinel配置:

yaml
# sentinel 配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080
        port: 9900
#dashboard: 8080 控制台端口
#port: 9900 本地启的端口,随机选个不能被占用的,与dashboard进行数据交互,会在应用对应的机器上
#启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互, 若被占用,则开始+1一次扫描

7.1 Sentinel自定义全局异常降级

在cloud-system中添加配置类,完成自定义降级异常

java
@Component
public class CloudSentinelBlockHandler implements BlockExceptionHandler {

    /*
        FlowException  //限流异常
        DegradeException  //降级异常
        ParamFlowException //参数限流异常
        SystemBlockException //系统负载异常
        AuthorityException //授权异常
     */

    /**
     *  V2.1.0 到  V2.2.0后,sentinel 里面依赖进行改动,且不向下兼容
     * @param request
     * @param response
     * @param e
     * @throws Exception
     */
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        /*
        request.getRequestURI() = /v1/user/list
        request.getRemoteUser() = null
        request.getContextPath() =
        request.getMethod() = GET
         */

        // 降级业务
        Map<String,Object> backMap=new HashMap<>();
        if (e instanceof FlowException){
            backMap.put("code",-1);
            backMap.put("msg","限流-异常啦");
        }else if (e instanceof DegradeException){
            backMap.put("code",-2);
            backMap.put("msg","降级-异常啦");
        }else if (e instanceof ParamFlowException){
            backMap.put("code",-3);
            backMap.put("msg","热点-异常啦");
        }else if (e instanceof SystemBlockException){
            backMap.put("code",-4);
            backMap.put("msg","系统规则-异常啦");
        }else if (e instanceof AuthorityException){
            backMap.put("code",-5);
            backMap.put("msg","认证-异常啦");
        }

        backMap.put("success",false);
        // 设置返回json数据
        response.setStatus(200);
        response.setHeader("content-Type","application/json;charset=UTF-8");
        response.getWriter().write(JSONObject.toJSONString(backMap));
    }

}

cloud-system中写好接口:

java
@RequiredArgsConstructor
@RequestMapping("/v1/user")
@RestController
public class UserController {

    private final UserService userService;

    @GetMapping("/list")
    public R listUser(){
        List<User> list = userService.list();
        return R.data(list);
    }
}

浏览器快速请求接口/v1/user/list验证自定义:Sentinel自定义异常降级

验证成功

7.2 Sentinel整合OpenFeign

cloud-system中添加配置:

yaml
# 开启 sentinel 对feign 的支持,一旦出错就会进入兜底数据
feign:
  sentinel:
    enabled: true

cloud-system中定义feign接口请求 cloud-order

java
@FeignClient(value = "cloud-order-service",fallback = OrderFeignClientFallback.class)
public interface OrderFeignClient {

    /**
     *  获取订单列表
     * @return
     */
    @GetMapping("/v1/order/list")
    R listOrder();

}

新建兜底类 OrderFeignClientFallback:

java
@Component
public class OrderFeignClientFallback implements OrderFeignClient {

    @Override
    public R listOrder() {
        // 请求另外服务出错就会进入到这里的兜底方法
        return R.fail("获取数据失败了,这是兜底数据哦。。。");
    }

}

cloud-system中编写测试接口

java
@RequiredArgsConstructor
@RequestMapping("/v1/user")
@RestController
public class UserController {

    private final OrderFeignClient orderFeignClient;

    @GetMapping("/listOrder")
    public R listOrder(){
        R r = orderFeignClient.listOrder();
        return r;
    }

}

请求接口:/v1/user/listOrder

测试只开启cloud-system 关闭cloud-order:

测试结果,进入兜底类,Sentinel整合OpenFeign 成功

单独设置:

熔断降级规则(DegradeRule)包含下面几个重要的属性:

Field说明默认值
resource资源名,即规则的作用对象
grade熔断策略,支持慢调用比例/异常比例/异常数策略慢调用比例
count慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow熔断时长,单位为 s
minRequestAmount熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)5
statIntervalMs统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)1000 ms
slowRatioThreshold慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

7.3 sentinel配置持久化

配置持久化到nacos

java
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

Data ID为 spring应用的名称:

json
[
  {
  "resource": "/findById",
  "limitApp":"default",
  "grade":1,
  "count":1,
  "strategy":0,
  "controlBehavior":0,
  "clusterMode":false
  }
]

naocs配置解读:

java
resource:资源名称
limitApp:来源应用
grade:阀值类型  【0---线程数,1---QPS】
count:单机阀值
strategy:流控模式,【0---直接,1---关联,2---链路】
controlBehavior:流控效果,【0---快速失败,1---warmUp,2---排队等待】
clusterMode:是否集群
  • 此时如果是Nacos集群,每个节点务必要配置到同一个数据库上。并且保证每个

    节点都可用。如果有的节点宕掉了可能会导致配置持久化失败。

  • 部署在nacos上的配置文件的名字并没有太多要求,只需要跟微服务项目中yml文件中配置的dataId一致即可。