SpringCloud Alibaba Sentinel

为什么需要服务熔断和降级

微服务是当前业界的一大趋势,原理就是将单一职责的功能模块独立化为子服务,降低服务间的耦合,服务间互相调用。但是这样也会出现一些问题:

  • 大量微服务互相调用,存在大量的依赖关系,难免会出现某个服务故障,然后变成级联故障,最终导致系统不可用的坍塌,也就是服务雪崩。

  • 当然还有某些场景,在一些时间段某些服务会出现高并发的情况,而某些服务占用着那些紧缺的资源显然是不太合理的,这时就需要对一些服务进行降级处理,削弱占用的系统资源。
    SpringCloud Alibaba Sentinel

服务熔断:根据保险丝的熔断是一个原理,当调用目标服务大量超时和失败,这时候应该熔断掉该服务的调用,从而快速释放资源,这段时间所有对其调用都是快速返回,保证整体服务系统的稳定

服务降级:针对核心业务服务的压力剧增,根据当前业务场景和流量对其他非核心服务进行降级处理,可以进行限流,快速返回等处理,释放资源保证核心任务的正常运行。
SpringCloud Alibaba Sentinel

针对这两个问题,微服务架构框架SpringCloud NetFlix的可靠性解决方案便是Hystrix。但是Hystrix现在进入了维护阶段不在进行后续的更新,这时我们就需要寻找一款微服务熔断策略的替代品。

Sentinel:分布式系统流量防卫兵

Sentinel 是一款由阿里开发的面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保护服务的稳定性。

Sentinel具有以下特征:

  • 应用场景:经受阿里近十年双11核心业务的流量考验
  • 实时监控:提供了实时监控功能,可以通过控制台为服务进行流量控制,熔断降级。并且支持集群下的运行管理
  • 开源生态:提供开箱即用的整合模块,可快速与SpringCloud、Dubbo、gRPC进行整合
  • SPI 扩展点:提供完善的SPI扩展接口。通过扩展接口定制规则管理、适配动态数据源。
  • 主要特性
    SpringCloud Alibaba Sentinel
    开源生态:
    SpringCloud Alibaba Sentinel

Hystrix与Sentinel

功能 Sentinel Hystrix
隔离策略 信号量隔离(并发线程数限流) 线程池隔离/信号量隔离
熔断降级策略 基于响应时间、异常比率、异常数 基于异常比率
实时统计实现 滑动窗口(LeapArray) 滑动窗口(基于RxJava)
动态规则配置 支持多种数据源 支持多种数据源
扩展性 多个扩展点 插件形式
基于注解的支持 支持 支持
限流 基于QPS,支持基于调用关系的限流 有限的支持
流量整形 支持预热模式、匀速器模式、预热排队模式 不支持
系统自适应保护 支持 不支持
控制台 可配置规则、查看秒级监控、机器发现等 简单的监控查看

HelloWorld

接入Sentinel

新建SpringBoot2.0项目,添加依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-alibaba-sentinel</artifactId>
	<version>0.2.1.RELEASE</version>
</dependency>

application.properties配置

spring.application.name=sentinel-demo
server.port=8090
spring.cloud.sentinel.transport.dashboard=localhost:8080

资源限流埋点

Sentinel默认为所有的HTTP服务提供限流埋点。引入依赖后自动完成所有埋点。只需要在控制配置限流规则即可
注解埋点

@Service
public class HelloService {

    @SentinelResource("test")
    public String hello(){
        return "Hello World Sentinel";
    }
}
@RestController
public class HelloController {

    @Resource
    HelloService helloService;

    @RequestMapping("/hello")
    public String hello(){
        return helloService.hello();
    }
}

部署控制台

安装

下载Sentineljar包
执行命令

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

打开浏览器访问:http://localhost:8080/#/dashboard/home
如果控制台没看到应用,先调用下Sentinel埋点的资源访问路径,或者禁用Sentinel的懒加载spring.cloud.sentinel.eager=true
访问资源查看。
SpringCloud Alibaba Sentinel

配置url限流

使用控制台配置限流url,点击新增流控规则,配置最大限流阈值设为1
SpringCloud Alibaba Sentinel

不断刷新页面可以发现会有限流响应效果
SpringCloud Alibaba Sentinel

配置资源限流

资源限流规则不是添加访问url,而是配置注解的Resource值。比如配置为SentinelResource("test")就是配置resource。
SpringCloud Alibaba Sentinel
刷新访问资源
SpringCloud Alibaba Sentinel

自定义限流

自定义资源限流

@SentinelResource 注解包含以下属性:

  • value: 资源名称,必需项(不能为空)
  • entryType: 入口类型,可选项(默认为 EntryType.OUT)
  • blockHandler:blockHandlerClass中对应的异常处理方法名。参数类型和返回值必须和原方法一致
  • blockHandlerClass:自定义限流逻辑处理类
    @SentinelResource(value = "test",blockHandler = "handleException",blockHandlerClass = {ExceptionUtil.class})
    public String hello(){
        return "Hello World Sentinel";
    }
public class ExceptionUtil {
    public static String handleException(BlockException ex) {
        return "自定义限流逻辑埋点";
    }

}

自定义url限流

public class CustomBlockHandler implements UrlBlockHandler {
    @Override
    public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
        httpServletResponse.setHeader("content-type", "text/html;charset=UTF-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write("url自定义限流异常");
    }
}
WebCallbackManager.setUrlBlockHandler(new CustomBlockHandler());