SpringCloud Alibaba Sentinel
为什么需要服务熔断和降级
微服务是当前业界的一大趋势,原理就是将单一职责的功能模块独立化为子服务,降低服务间的耦合,服务间互相调用。但是这样也会出现一些问题:
-
大量微服务互相调用,存在大量的依赖关系,难免会出现某个服务故障,然后变成级联故障,最终导致系统不可用的坍塌,也就是服务雪崩。
-
当然还有某些场景,在一些时间段某些服务会出现高并发的情况,而某些服务占用着那些紧缺的资源显然是不太合理的,这时就需要对一些服务进行降级处理,削弱占用的系统资源。
服务熔断:根据保险丝的熔断是一个原理,当调用目标服务大量超时和失败,这时候应该熔断掉该服务的调用,从而快速释放资源,这段时间所有对其调用都是快速返回,保证整体服务系统的稳定
服务降级:针对核心业务服务的压力剧增,根据当前业务场景和流量对其他非核心服务进行降级处理,可以进行限流,快速返回等处理,释放资源保证核心任务的正常运行。
针对这两个问题,微服务架构框架SpringCloud NetFlix的可靠性解决方案便是Hystrix。但是Hystrix现在进入了维护阶段不在进行后续的更新,这时我们就需要寻找一款微服务熔断策略的替代品。
Sentinel:分布式系统流量防卫兵
Sentinel 是一款由阿里开发的面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保护服务的稳定性。
Sentinel具有以下特征:
- 应用场景:经受阿里近十年双11核心业务的流量考验
- 实时监控:提供了实时监控功能,可以通过控制台为服务进行流量控制,熔断降级。并且支持集群下的运行管理
- 开源生态:提供开箱即用的整合模块,可快速与SpringCloud、Dubbo、gRPC进行整合
- SPI 扩展点:提供完善的SPI扩展接口。通过扩展接口定制规则管理、适配动态数据源。
- 主要特性
开源生态:
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
访问资源查看。
配置url限流
使用控制台配置限流url,点击新增流控规则,配置最大限流阈值设为1
不断刷新页面可以发现会有限流响应效果
配置资源限流
资源限流规则不是添加访问url,而是配置注解的Resource值。比如配置为SentinelResource("test")
就是配置resource。
刷新访问资源
自定义限流
自定义资源限流
@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());