熔断限流渐渐从Hystrix转为Sentinel

发布于:2024-04-30 ⋅ 阅读:(30) ⋅ 点赞:(0)

前言

现在的微服务渐渐在版本更新迭代中,在框架升级方面,涉及到服务的限流方面渐渐的从最早的Spring Cloud的Hystrix组件,慢慢转变为阿里开源的微服务熔断限流技术组件Sentinel,那么为什么要用Sentinel呢,它跟Hystrix的区别性能方面到底差距在哪?

Hystrix

Hystrix是Spring Cloud生态下的一个对服务提供,熔断、接口降级、限流的一个组件,是Netflix开源的限流组件 ,如今已经不在更新新的功能了;

Hystrix两个比较核心概念就是:线程池隔离信号量隔离

线程池隔离

在微服务的调用过程中,如果所有接口都在一个线程池中调用,某些接口在大规模请求的情况下,就会导致服务的资源耗尽,导致服务的崩溃; 所有遇到这种场景下,Hystrix会将不同接口放到不同的线程池中进行处理,线程池之前相互不干扰,可以避免一个线程池出现故障,不影响其他的服务调用;

36337F13-8F98-43F6-A5C2-4F253C14BAD1.png

下面来看具体线程池隔离使用,可以看到作用在方法上还是需要很多的配置,不同的方法可以使用不同的线程池进行执行,相互隔离;

E87213C4-C177-4244-82ED-92E32EEAF468.png

信号量隔离

Hystrix通过设置信号量,这个信号量可以代表接口同时访问的最大请求数,如果超过了这个信号量阀值将会触发失败机制,或者进行阻塞等待;

70982D2A-646E-423F-B4A2-715B69EC0369.png

下面是Hystrix信号量配置,也是使用@HystrixCommand注解,配置指定隔离策略;

26F8BBF2-9921-44D1-9691-6D7286C6D5ED.png

Sentinel

Sentinel 和Hystrix对比,总体看下来还是Sentinel更香一点;

84BF3ACB-3BD9-4007-9B1E-5E0847219431.png

实时监控:Sentinel提供实时监控页面,可以在控制台看到注册服务的QPS; 开源生态整合:经常使用的微服务框架 Spring Cloud、Dubbo、grpc,只需要引入相应的依赖即可; 扩展度:易于扩展,可对SPI进行定制适配逻辑;

Sentinel通信原理

F9238448-A0DE-4ABA-AB7C-B1B08FEE25A0.png

Sentinel服务端搭建

  • 执行命令获取sentinel镜像
docker pull alibaba/sentinel-dashboard
  • 运行sentinel容器
  • docker run -d -p 8858:808858—name sentinel-dashboard alibaba/sentinel-dashboard
  • 默认账户/密码:sentinel ,登录进来可以看到Sentinel控制台(dashboard)

38D0E27B-9836-41A8-BE70-C67C1208834A.png

Spring-Cloud Alibaba整合Sentinel

引入Sentinel依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

Gateway网关接入Sentinel,一般服务的调用都要经过网关的转发,所以在网关层面做客户端的接入;

sentinel:
  # 取消控制台懒加载
  eager: true
  transport:
    # 控制台地址
    dashboard: 127.0.0.1:8858
  # nacos配置持久化
  datasource:
    ds1:
      nacos:
        server-addr: 127.0.0.1:8848
        dataId: sentinel-pms-gateway
        groupId: DEFAULT_GROUP
        data-type: json
        rule-type: gw-flow

  • Sentinel降级处理类
public class SentinelFallbackHandler implements WebExceptionHandler {

    private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
        return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试");
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        if (exchange.getResponse().isCommitted()) {
            return Mono.error(ex);
        }
        if (!BlockException.isBlockException(ex)) {
            return Mono.error(ex);
        }
        return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
    }

    private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) {
        return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
    }
}

  • 配置GatewayConfig,使用SentinelFallbackHandler策略
@Configuration
public class GatewayConfig {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelFallbackHandler sentinelGatewayExceptionHandler(){
        return new SentinelFallbackHandler();
    }
}
  • sentinel-pms-gateway,Sentinel限流策略配置持久化在nacos中;
[    {        "resource": "pms-system",        "count": 1000,        "grade": 1,        "limitApp": "default",        "strategy": 0,        "controlBehavior": 0    }]

定义规则

具体限流、降级策略可以在控制台进行配置;

AE08CAB9-78CE-4E93-A1FF-6CBE66995B55.png 当然也可以在代码里通过FlowRule类进行配置

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

总结

总体来说现在接口限流方面,基本很多公司优先会选择Sentinel,其功能更加完善,使用相对更加简单,主要可以直观看到服务的各种信息,所以很多公司在基础架构升级方面将限流方面的框架从Hystrix升级为Sentinel;