前言
现在的微服务渐渐在版本更新迭代中,在框架升级方面,涉及到服务的限流方面渐渐的从最早的Spring Cloud的Hystrix组件,慢慢转变为阿里开源的微服务熔断限流技术组件Sentinel,那么为什么要用Sentinel呢,它跟Hystrix的区别性能方面到底差距在哪?
Hystrix
Hystrix是Spring Cloud生态下的一个对服务提供,熔断、接口降级、限流的一个组件,是Netflix开源的限流组件 ,如今已经不在更新新的功能了;
Hystrix两个比较核心概念就是:线程池隔离 和信号量隔离
线程池隔离
在微服务的调用过程中,如果所有接口都在一个线程池中调用,某些接口在大规模请求的情况下,就会导致服务的资源耗尽,导致服务的崩溃; 所有遇到这种场景下,Hystrix会将不同接口放到不同的线程池中进行处理,线程池之前相互不干扰,可以避免一个线程池出现故障,不影响其他的服务调用;

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

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

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

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

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

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

Spring-Cloud Alibaba整合Sentinel
引入Sentinel依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
Gateway网关接入Sentinel,一般服务的调用都要经过网关的转发,所以在网关层面做客户端的接入;
yaml
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降级处理类
kotlin
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策略
less
@Configuration
public class GatewayConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler(){
return new SentinelFallbackHandler();
}
}
- sentinel-pms-gateway,Sentinel限流策略配置持久化在nacos中;
css
[ { "resource": "pms-system", "count": 1000, "grade": 1, "limitApp": "default", "strategy": 0, "controlBehavior": 0 }]
定义规则
具体限流、降级策略可以在控制台进行配置;
当然也可以在代码里通过FlowRule类进行配置
scss
@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;