Spring Cloud Alibaba整合Sentinel

Sentinel快速开始

在官方文档中,定义的Sentinel进行资源保护的几个步骤:

  1. 定义资源
  2. 定义规则
  3. 检验规则是否生效
Entry entry = null;
// 务必保证 finally 会被执行
try {
  // 资源名可使用任意有业务语义的字符串  开启资源的保护
  entry = SphU.entry("自定义资源名");
  // 被保护的业务逻辑    method
  // do something...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级   Sentinel定义异常  流控规则,降级规则,热点参数规则。。。。   服务降级(降级规则)
  // 进行相应的处理操作
} catch (Exception ex) {
  // 若需要配置降级规则,需要通过这种方式记录业务异常    RuntimeException     服务降级   mock  feign:fallback 
  Tracer.traceEntry(ex, entry);
} finally {
  // 务必保证 exit,务必保证每个 entry 与 exit 配对
  if (entry != null) {
    entry.exit();
  }

Sentinel资源保护的方式

API实现

引入依赖


     com.alibaba.csp
     sentinel-core
     1.8.0
  1. 编写测试逻辑
@RestController
@Slf4j
public class HelloController {

    private static final String RESOURCE_NAME = "hello";

    @RequestMapping(value = "/hello")
    public String hello() {

        Entry entry = null;
        try {
            // 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
            entry = SphU.entry(RESOURCE_NAME);
            // 被保护的业务逻辑
            String str = "hello world";
            log.info("====="+str);
            return str;
        } catch (BlockException e1) {
            // 资源访问阻止,被限流或被降级
            //进行相应的处理操作
            log.info("block!");
        } catch (Exception ex) {
            // 若需要配置降级规则,需要通过这种方式记录业务异常
            Tracer.traceEntry(ex, entry);
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
        return null;
    }

    /**
     * 定义流控规则
     */
    @PostConstruct
    private static void initFlowRules(){
        List rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        //设置受保护的资源
        rule.setResource(RESOURCE_NAME);
        // 设置流控规则 QPS
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置受保护的资源阈值
        // Set limit QPS to 20.
        rule.setCount(1);
        rules.add(rule);
        // 加载配置好的规则
        FlowRuleManager.loadRules(rules);
    }
}

缺点:

  • 业务侵入性很强,需要在controller中写入非业务代码.
  • 配置不灵活 若需要添加新的受保护资源 需要手动添加 init方法来添加流控规则

@SentinelResource注解实现

@SentinelResource 注解用来标识资源是否被限流、降级。

blockHandler: 定义当资源内部发生了BlockException应该进入的方法(捕获的是Sentinel定义的异常)

fallback: 定义的是资源内部发生了Throwable应该进入的方法

exceptionsToIgnore:配置fallback可以忽略的异常

源码入口:com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect

1.引入依赖


    com.alibaba.csp
    sentinel-annotation-aspectj
    1.8.0

2.配置切面支持

@Configuration
public class SentinelAspectConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}

3.UserController中编写测试逻辑,添加@SentinelResource,并配置blockHandler和fallback

@RequestMapping(value = "/findOrderByUserId/{id}")
@SentinelResource(value = "findOrderByUserId",
                  fallback = "fallback",fallbackClass = ExceptionUtil.class,
                  blockHandler = "handleException",blockHandlerClass = ExceptionUtil.class
                 )
public R  findOrderByUserId(@PathVariable("id") Integer id) {
    //ribbon实现
    String url = "http://mall-order/order/findOrderByUserId/"+id;
    R result = restTemplate.getForObject(url,R.class);

    if(id==4){
        throw new IllegalArgumentException("非法参数异常");
    }

    return result;
}

4.编写ExceptionUtil,注意如果指定了class,方法必须是static方法

public class ExceptionUtil {

    public static R fallback(Integer id,Throwable e){
        return R.error(-2,"===被异常降级啦===");
    }

    public static R handleException(Integer id, BlockException e){
        return R.error(-2,"===被限流啦===");
    }
}

5.流控规则设置可以通过Sentinel dashboard配置

客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。


    com.alibaba.csp
    sentinel-transport-simple-http
    1.8.0

6. 启动 Sentinel 控制台

下载控制台 jar 包并在本地启动:可以参见 此处文档

#启动控制台命令 java -jar sentinel-dashboard-1.8.0.jar

用户可以通过如下参数进行配置:

-Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel;

-Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel;

-Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

访问http://localhost:8080/#/login ,默认用户名密码: sentinel/sentinel

Spring Cloud Alibaba整合Sentinel

1.引入依赖


com.alibaba.cloud
spring‐cloud‐starter‐alibaba‐sentinel


org.springframework.boot
spring‐boot‐starter‐actuator

2.添加yml配置, 为微服务设置 sentinel 控制台地址
添加Sentinel后,需要暴露/actuator/sentinel端点,而Springboot默认是没有暴露该端点的,所以需要设置,测试
http://localhost:8800/actuator/sentinel
server:
  port: 8800

spring:
  application:
    name: mall-user-sentinel-demo
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    sentinel:
      transport:
        # 添加sentinel的控制台地址
        dashboard: 127.0.0.1:8080
        # 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
        # port: 8719
    
#暴露actuator端点   
management:
  endpoints:
    web:
      exposure:
        include: '*'

在sentinel控制台中设置流控规则

  • 资源名: 接口的API
  • 针对来源: 默认是default,当多个微服务都调用这个资源时,可以配置微服务名来对指定的微服务设置阈值
  • 阈值类型: 分为QPS和线程数 假设阈值为10
  • QPS类型: 只得是每秒访问接口的次数>10就进行限流
  • 线程数: 为接受请求该资源分配的线程数>10就进行限流

微服务和Sentinel Dashboard通信原理

Sentinel控制台与微服务端之间,实现了一套服务发现机制,集成了Sentinel的微服务都会将元数据传递给Sentinel控制台

Spring Cloud Alibaba整合Sentinel_第1张图片

 

你可能感兴趣的:(微服务,sentinel,spring,boot,java)