Alibaba Sentinel整合SpringBoot,为微服务保驾护航!

 前言

        随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。


正文

1. Sentinel特征

        Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

        Sentinel具有以下特征:

  1.  丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控 制在统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等;
  2. 完备的实时监控:   Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据, 甚至 500 台以下规模的集群的汇总运行情况。
  3. 广泛的开源生态:   Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring CloudDubbo gRPC 合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel
  4. 完善的 SPI 扩展点:   Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。 例如定制规则管理、适配数据源等。

        阿里云提供了 企业级的 Sentinel 服务,  应用高可用服务 AHAS。

        Sentinel和Hystrix对比:

Sentinel Hystrix
隔离策略 信号量隔离 线程池隔离/信号量隔离
熔断降级策略 基于相应时间或失败比率 基于失败比率
实时指标实现 滑动窗口 滑动窗口(基于RxJava)
规则配置 支持多种数据源 支持多种数据源
扩展性 多个扩展点 插件的形式
基于注解支持 支持 支持
限流 基于QPS,支持基于调用关系的限流 有限的支持
流量整形 支持满启动,匀速器模式 不支持
系统负载保护 支持 不支持
控制台

开箱即用,可配置规则,查看秒级监控,机器发现等

不支持
常见框架的适配 Servlet,Spring Cloud,Dubbo,gRPC等 Servlet,Spring Cloud Netflix

        Sentinel和Hystrix都是开源,但是目前Hystrix的Netflix团队已经不在维护了,而Sentinel阿里团队一直在迭代更新,社区也在不断发展。

        性能方面,Sentinel比Hystrix更加轻量级,性能也更好一点,并且经过了双十一阿里的超大流量考验。


2. Sentinel快速开始

2.1 API实现

  • 引入依赖

<dependency>

        <groupId>com.alibaba.csp</groupId>

        <artifactId>sentinel core</artifactId>

        <version>1.8.0</version>

</dependency>

  • 代码实现

        在官方文档中,定义的Sentinel进行资源保护需要先定义资源和规则。

@Slf4j
@RestController
@RequestMapping(value = "/sentinel")
public class TestSentinelController {

    private static final String RESOURCE_NAME	=	"hello";

    /**
     *	编写测试代码,对"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<FlowRule> 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);
    }
}
  • 测试效果

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

2.2 @SentinelResource注解实现

  • 引入依赖
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel‐annotation‐aspectj</artifactId>
    <version>1.8.0</version>
</dependency>
  • 配置切面支持
@Configuration
public class SentinelAspectConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();  
    }
}
  • 编写测试逻辑,添加@SentinelResource,配置blockHandlerfallback
@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; 
}
  • 编写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, "===被限流啦===");
    }                                                                                                                  	}
  • 流控规则设置可以通过Sentinel dashboard配置

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

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel‐transport‐simple‐http</artifactId>
    <version>1.8.0</version>
</dependency>

        application.yml:客户端需要配置 Sentinel 控制台【IP:端口】进行通信。

Dcsp.sentinel.dashboard.server=consoleIp:port


3. 启动 Sentinel 控制台

        下载控制台 jar 包并在本地启动:可以参见官网文档https://github.com/alibaba/Sentinel/releases

  • jar包的控制台启动命令

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

        其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080

         从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。可以参考 鉴权模块文档 配置用户名和密码。

        Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包,所以要确保客户端有访问量。

  • 查看机器列表以及健康情况

        当您在机器列表中看到您的机器,就代表着您已经成功接入控制台;如果没有看到您的机器,请检查配置,并通过 ${user.home}/logs/csp/sentinel-record.log.xxx 日志来排查原因。

  • Sentinel控制台


4. Spring Cloud Alibaba整合Sentinel

  • 引入依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring‐cloud‐starter‐alibaba‐sentinel</artifactId>  
</dependency>
  •  添加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
  • sentinel控制台中设置流控规

  • 微服务和Sentinel Dashboard通信原理

        Sentinel控制台与微服务端之间,实现了一套服务发现机制,集成了Sentinel的微服务都会将元数据传递给Sentinel控制 台,架构图如下所示:


猜你喜欢

转载自blog.csdn.net/weixin_44259720/article/details/130677425