Spring Cloud Alibaba —— 服务容错 Sentinel

Updated on in Java with 683 views

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/ ,账号密码均为 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:当系统 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

Responses
取消