侧边栏壁纸
博主头像
术业有道之编程博主等级

亦是三月纷飞雨,亦是人间惊鸿客。亦是秋霜去叶多,亦是风华正当时。

  • 累计撰写 99 篇文章
  • 累计创建 50 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

springcloud alibaba 之 sentinel

Administrator
2020-09-01 / 0 评论 / 0 点赞 / 87 阅读 / 9329 字

大名鼎鼎的 sentinel 没用过的都想用,用过都说好,下面是集成过程。

项目源码

在开始之前首先需要看一下

一、搭建 sentinel 服务

sentinel docker 选择以下一种即可

sentinel:
  container_name: sentinel-dashboard
  image: registry.cn-hangzhou.aliyuncs.com/lcts/sentinel-dashboard:1.7.1
  restart: always
  ports:
    - "8858:8080"
  environment:
      TZ : "Asia/Shanghai"

会在本地端口 8858 启动一个 sentinel 服务

访问 http://localhost:8858 默认账户和密码是 sentinel

二、在项目中集成 sentinel

  • maven 依赖
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
<!--提供 sentinel 监控-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- sentinel 与 dubbo2.7.x以上的整合包 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-apache-dubbo-adapter</artifactId>
            <version>1.7.1</version>
        </dependency>
        <!-- sentinel 提供 AspectJ 的扩展用于自动定义资源、处理 BlockException等 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
            <version>1.7.1</version>
        </dependency>
  • 基于 bean 的配置
/**
 * Sentinel 配置
 */
@Configuration
public class SentinelConfiguration {

    /**
     * 配置方法级别的Sentinel aop
     */
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }

    /**
     * 让web层请求都经过 sentinelFilter,如果不需要监控web层 可以去掉这个方法
     */
    @Bean
    public FilterRegistrationBean sentinelFilterRegistration() {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CommonFilter());
        registration.addUrlPatterns("/*");
        registration.setName("sentinelFilter");
        registration.setOrder(1);

        return registration;
    }
}
  • 启动配置中增加
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8858
    nacos:
      discovery:
        server-addr: localhost:8848  #Nacos服务器侦听器的IP和端口 #80不能省略
        weight:  10 # 值范围:1到100。值越大,权重越大

三、在项目中使用 sentinel

  • 演示在 controller 层的使用
@RestController
@RequestMapping("/config")
public class ConfigController {

    @Value("${spring.profiles.active}")
    String active;
    @Autowired
    RestTemplate restTemplate;

    /**
     * http://localhost:8080/config/get
     */
    @GetMapping("get")
    public String get(@RequestParam(required = false) String str) {
        return active + " | " + str;
    }

    /**
     * http://localhost:8080/config/rest
     */
    @SentinelResource("ss")
    @GetMapping("rest")
    public String rest() {
        return restTemplate.getForObject("http://nacos-provider/config/get/" + "?str=consumerSend", String.class);
    }
}

  • 基于业务实现层的使用
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.lc.cloud.alibaba.api.TestDubboService;
import com.lc.cloud.alibaba.consumer.fuse.SentinelTestServiceBlockHandler;
import com.lc.cloud.alibaba.consumer.fuse.SentinelTestServiceFallbackHandler;
import com.lc.cloud.alibaba.consumer.domain.service.SentinelTestService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Service
public class SentinelTestServiceImpl implements SentinelTestService {
    @Reference
    TestDubboService testDubboService;

    /*******
     * 注意 :若 blockHandler 和 fallback 都进行了配置
     * 则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑
     */
    @SentinelResource(blockHandler = "get2BlockHandler",
            blockHandlerClass = {SentinelTestServiceBlockHandler.class},
            fallback = "get1FallbackHandler",
            fallbackClass = {SentinelTestServiceFallbackHandler.class})
    @Override
    public String get(String str) {
        if (1 == 1) throw new RuntimeException("自定义异常");
        return testDubboService.get(str);
    }

    @SentinelResource(blockHandler = "get2BlockHandler",
            blockHandlerClass = {SentinelTestServiceBlockHandler.class})
    @Override
    public String get2(String str) {
        if (1 == 1) throw new RuntimeException("自定义异常");
        return testDubboService.get2(str);
    }

    @SentinelResource(fallback = "get3Fallback")
    @Override
    public String get3(String str) {
        if (1 == 1) throw new RuntimeException("自定义异常");
        return testDubboService.get3(str);
    }

    //这里的服务降级或回退方法只需要  public 修饰
    public String get2BlockHandler(String str) {
        return "get2BlockHandler :" + str;
    }

    public String get3Fallback(String str) {
        return "get3Fallback :" + str;
    }
}
注意:
  • 最灵性的地方在于 @SentinelResource 注解,想要哪个被监控就加哪个,上面基于 bean 配置的时候已经加入了 web 层 ,所以 web层不需要显式使用这个注解了

  • blockHandlerClass fallbackClass 对应的方法 必须是 public static 修饰 ,而且调用优先级最高。也就是在有

blockHandler   
fallback  
blockHandlerClass 
fallbackClass

都存在的情况下,只会调用 blockHandlerClass fallbackClass

  • 需要特别注意的是 @SentinelResource 下面的这几个属性的用法,这里不使用篇幅介绍了,可以直接去看本项目源码,或者 sentinel 文档
 /**
     * @return name of the Sentinel resource
     */
    String value() default "";
/**
     * @return name of the block exception function, empty by default
     */
    String blockHandler() default "";

    /**
     * The {@code blockHandler} is located in the same class with the original method by default.
     * However, if some methods share the same signature and intend to set the same block handler,
     * then users can set the class where the block handler exists. Note that the block handler method
     * must be static.
     *
     * @return the class where the block handler exists, should not provide more than one classes
     */
    Class<?>[] blockHandlerClass() default {};

    /**
     * @return name of the fallback function, empty by default
     */
    String fallback() default "";

    /**
     * The {@code defaultFallback} is used as the default universal fallback method.
     * It should not accept any parameters, and the return type should be compatible
     * with the original method.
     *
     * @return name of the default fallback method, empty by default
     * @since 1.6.0
     */
    String defaultFallback() default "";

    /**
     * The {@code fallback} is located in the same class with the original method by default.
     * However, if some methods share the same signature and intend to set the same fallback,
     * then users can set the class where the fallback function exists. Note that the shared fallback method
     * must be static.
     *
     * @return the class where the fallback method is located (only single class)
     * @since 1.6.0
     */
    Class<?>[] fallbackClass() default {};

四、在监控面板中使用 sentinel

访问 http://localhost:8858 默认账户和密码是 sentinel 后 请求上面的示例,你会看到惊喜,更多用法请参考 sentinel 文档

到此 sentinel 集成完成

个人公众号

0

评论区