Spring Cloud Alibaba —— 服务容错 Sentinel

Published on in Java with 0 views and 0 comments

Sentinel 是阿里巴巴开源的一款服务容错组件,本来打算整理下 Feign 或者 Ribbon 的使用方法,但这两个组件在使用 Spring Cloud 曾经用过,而笔者刚接触 Sentinel 这个微服务组件不久,所以打算记录下 Sentinel 的一些玩法。

常见的容错方案

Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户提升服务的稳定性。说到这熔断,美股几天前刚刚也触发了熔断机制,上者熔断是为了保护业务服务器,而股市中的熔断通过暂停交易防止对市场造成更大的冲击,两者还真有异曲同工之妙哈。Sentinel的常见的容错方案有下面四种:

  1. 超时:通过超时来释放资源,这样服务器不会被错误的业务或大流量拖死

  2. 限流:通过评估流量来限制流量的QPS

  3. 舱壁模式(Bulkhead):保护有限资源不被耗尽,从而保护整个系统的安全。每个资源有自己独立的线程池,如果微服务A出现异常,则不会影响微服务B的调用
    image.png

  4. 断路器模式:监控错误率达到一定阈值时则跳闸,断路器有打开、关闭、半开三态,而Sentinel目前还没有实现半开状态。断路器模式的详细介绍可以看 Martin Fowler 的这篇文章:https://martinfowler.com/bliki/CircuitBreaker.html

安装和启动Sentinel Dashboard

  1. 从GitHub:https://github.com/alibaba/Sentinel/releases 下在文档版本的Sentinel Dashboard 的jar包
  2. 使用 java -jar sentinel-dashboard-1.6.3.jar ,这里换成对应jar包版本,启动控制台
  3. 访问 http://127.0.0.1:8080/ ,账号密码均为sentinel,看到如下界面:
    image.png
  • 指定控制台的登录用户名:-Dsentinel.dashboard.auth.username=username
  • 指定控制台的登录密码:-Dsentinel.dashboard.auth.password=password
  • 指定控制台的Session过期时间:-Dserver.servlet.session.timeout=7200 如 7200 表示 7200 秒;60m 表示 60 分钟(默认为 30 分钟)

加依赖和配置

maven 依赖如下:

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

application.yml 加入 sentinel 配置

sentinel:
    transport:
        dashboard: 127.0.0.1:8080

添加规则

当依赖和配置添加完毕后,启动自己的微服务业务,然后访问一个端点,由于Sentinel 的懒加载机制,必须先访问一次微服务业务接口,才能出现左侧配置规则的导航栏,之后尝试添加一个流控规则。

流控

image.png

流控规则QPS设置为1,疯狂刷新配置的端点,就会出现被流控的现象,到这一步Sentinel也算玩起来了。

高级选型下有三种流控模式:

image.png

  • 直接:对配置的端点达到阈值时直接流控
  • 关联:当关联的资源到达阈值时,就限流自己的端点(保护关联资源)
  • 链路:只记录链路上的流量

流控的效果也有三种分别是:快速失败、Warm Up、排队等待

降级

降级规则有下面三种:

  • RT:平均响应时间,最大 4900ms,超过时需要下面方式修改 -Dcsp.sentinel.statistic.max.rt=xxx
  • 异常比例:资源的每秒异常总数占通过量的比值超过阈值则降级
  • 异常数:注意时间窗口不能小于 60,因为它是分钟级别

热点规则

对参数限流,构造一个有两个参数的端点,然后配置一下热点规则

@GetMapping("hot")
@SentinelResource("hot")
public String testHot(@RequestParam(required = false) String a, @RequestParam(required = false) String b) {
        return a + " " + b;
}

image.png

参数索引是从下标为0开始的,则这里配置的1表示参数“b”,当该参数为“hello”时,QPS限制为1。

系统规则

系统规则有一下四种:

  • Load:load1 当系统 1 分钟的 load 超过阈值,且并发线程数超过系统容量时就会触发,建议设置为 CPU 核数*2.5。(仅对 Linux 和 Unix-like 生效),可以通过uptime 查看
  • RT:所有入口流量的平均 RT 达到阈值触发
  • 线程数:所有入口流量的并发线程数就会触发
  • 入口 QPS:所有入口流量的 QPS 达到阈值触发

Sentinel规则持久化

Sentinel规则持久化有两种方案,推模式和拉模式,具体配置代码比较多,不贴出来了,不过生产环境下更推荐使用推模式(使用Alibaba Ahas的话略过)。

推模式架构图:

image.png

拉模式架构图:

image.png

自定义异常返回

默认 Sentinel 的异常返回是一段小字,提示并不友好,也无法区分到底是限流了还剩降级了,好在官方提供了 UrlBlockHandler 接口,通过实行这个接口就能自定义异常返回了。

/**
 * 自定义流控降级等异常处理
 */
@Component
public class MyUrlBlockHandler implements UrlBlockHandler {
    @Override
    public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException {
        ErrorMsg msg = null;
        if (e instanceof FlowException) {
            msg = ErrorMsg.builder()
                .status(100)
                .msg("限流了")
                .build();
        } else if (e instanceof DegradeException) {
            msg = ErrorMsg.builder()
                .status(102)
                .msg("降级了")
                .build();
        } else if (e instanceof ParamFlowException) {
            msg = ErrorMsg.builder()
                .status(103)
                .msg("热点参数限流")
                .build();
        } else if (e instanceof SystemBlockException) {
            msg = ErrorMsg.builder()
                .status(104)
                .msg("系统规则,负载..等不满足要求")
                .build();
        } else if (e instanceof AuthorityException) {
            msg = ErrorMsg.builder()
                .status(104)
                .msg("授权规则不通过")
                .build();
        }
        // HTTP状态码
        response.setStatus(500);
        response.setCharacterEncoding("utf-8");
	response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        new ObjectMapper().writeValue(response.getWriter(), msg);
    }
}

@Data
@Builder
class ErrorMsg {
    private Integer status;
    private String msg;
}

Sentinel 的知识点的确很多,这里并没有一一记录,学以致用,就算没用到也要记下来,这样就算以后忘了,还能翻阅回来看看。


标题:Spring Cloud Alibaba —— 服务容错 Sentinel
作者:Jeffrey