Spring Cloud Alibaba,服务熔断与限流(五)(下)

简介: Spring Cloud Alibaba,服务熔断与限流(五)

下面我们来在 Web 应用中针对 Dubbo consumer 来配置慢调用熔断规则,并模拟慢调用来观察效果。我们在 web-api-demo 中针对 com.alibaba.csp.sentinel.demo.dubbo.FooService 服务调用配置熔断降级规则。image.png控制台配置的统计时长默认为 1s。在上面的这条规则中,我们设定慢调用临界值为 50ms,响应时间超出 50ms 即记为慢调用。当统计时长内的请求数 >=5 且慢调用的比例超出我们配置的阈值(80%)就会触发熔断,熔断时长为 5s,经过熔断时长后会允许一个请求探测通过,若请求正常则恢复,否则继续熔断。

我们的实例中 /demo/time API 可以通过 slow 请求参数模拟慢调用,当 slow=true 时该请求耗时会超过 100ms。我们可以用 ab 等压测工具或脚本,批量请求 localhost:8090/demo/time?slow=true,可以观察到熔断的返回

image.png如果我们一直模拟慢调用,我们可以观察到熔断后每 5s 会允许通过一个请求,但该请求仍然是慢调用,会重新打回熔断,无法恢复。我们可以在触发熔断后,等待一段时间后手动发一个不带 slow=true 的正常请求,然后再进行请求,可以观察到熔断恢复。

需要注意的是,即使服务调用方引入了熔断降级机制,我们还是需要在 HTTP 或 RPC 客户端配置请求超时时间,来做一个兜底的防护。

注解方式自定义埋点

刚才我们看到的埋点都是 Sentinel 适配模块提供的自动埋点。有的时候自动埋点可能没法满足我们的需求,我们希望在某个业务逻辑的位置进行限流,能不能做到呢?当然可以!Sentinel 提供两种方式进行自定义埋点:SphU API 和 @SentinelResource 注解,前者最为通用但是代码比较繁杂,耦合度较高;注解方式侵入性较低,但有使用场景的限制。这里我们来动手在 Web 应用的 DemoService 上添加注解,来达到针对本地服务埋点的目标。

DemoService 中我们实现了一个简单的打招呼的服务:

@Service
public class DemoService {
    public String bonjour(String name) {
        return "Bonjour, " + name;
    }
}

下面我们给 bonjour 这个函数添加 @SentinelResource 注解,注解的 value 代表这个埋点的名称(resourceName),会显示在簇点链路/监控页面。

@SentinelResource(value = "DemoService#bonjour")
public String bonjour(String name)

加上该注解后,再通过网关访问 /demo/bonjour/{name} 这个 API 的时候,我们就可以在簇点链路页面看到我们自定义的 DemoService#bonjour 埋点了。image.png添加注解埋点只是第一步。一般在生产环境中,我们希望在这些自定义埋点发生限流的时候,有一些 fallback 逻辑,而不是直接对外抛出异常。这里我们可以写一个 fallback 函数:

public String bonjourFallback(Throwable t) {
    if (BlockException.isBlockException(t)) {
        return "Blocked by Sentinel: " + t.getClass().getSimpleName();
    }
    return "Oops, failed: " + t.getClass().getCanonicalName();
}

我们的 fallback 函数接受一个 Throwable 参数,可以从中获取异常信息。Sentinel 注解的 fallback 会捕获业务异常和流控异常(即 BlockException 及其子类),我们可以在 fallback 逻辑里面进行相应的处理(如日志记录),并返回 fallback 的值。

注意:Sentinel 注解对 fallback 和 blockHandler 函数的方法签名有要求,具体请参考此处文档。

写好 fallback 函数的实现后,我们在 @SentinelResource 注解里面指定一下:

@SentinelResource(value = "DemoService#bonjour", defaultFallback = "bonjourFallback")
public String bonjour(String name)

这样当我们自定义的 DemoService#bonjour 资源被限流或熔断的时候,请求会走到 fallback 的逻辑中,返回 fallback 结果,而不会直接抛出异常。我们可以配一个 QPS=1 的限流规则,然后快速请求后观察返回值:

?  ~ curl http://localhost:8090/demo/bonjour/Sentinel
Bonjour, Sentinel
?  ~ curl http://localhost:8090/demo/bonjour/Sentinel
Blocked by Sentinel: FlowException

注意:使用 @SentinelResource 注解要求对应的类必须由 Spring 托管(即为 Spring bean),并且不能是内部调用(没法走到代理),不能是 private 方法。Sentinel 注解生效依赖 Spring AOP 动态代理机制。

配置自定义的流控处理逻辑

Sentinel 的各种适配方式均支持自定义的流控处理逻辑。以 Spring Web 适配为例,我们只需要提供自定义的 BlockExceptionHandler 实现并注册为 bean 即可为 Web 埋点提供自定义处理逻辑。其中 BlockExceptionHandler 的定义如下:

public interface BlockExceptionHandler {
    // 在此处处理限流异常,可以跳转到指定页面或返回指定的内容
    void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception;
}

我们的 Web 应用中提供了 Web 埋点自定义流控处理逻辑的示例:

@Configuration
public class SentinelWebConfig {
    @Bean
    public BlockExceptionHandler sentinelBlockExceptionHandler() {
        return (request, response, e) -> {
            // 429 Too Many Requests
            response.setStatus(429);
            PrintWriter out = response.getWriter();
            out.print("Oops, blocked by Sentinel: " + e.getClass().getSimpleName());
            out.flush();
            out.close();
        };
    }
}

该 handler 会获取流控类型并打印返回信息,返回状态码为 429。我们可以根据实际的业务需求,配置跳转或自定义的返回信息。

对于注解方式,我们上一节已经提到,可以指定 fallback 函数来处理流控异常和业务异常,这里不再展开讲解;对于 Dubbo 适配,我们可以通过 DubboAdapterGlobalConfig 注册 provider/consumer fallback 来提供自定义的流控处理逻辑;对于 Spring Cloud Gateway 适配,我们可以注册自定义的 BlockRequestHandler 实现类来为网关流控注册自定义的处理逻辑。

对 Spring Cloud 其他组件的支持

Spring Cloud Alibaba Sentinel 还提供对 Spring Cloud 其它常用组件的支持,包括 RestTemplate、Feign 等。篇幅所限,我们不展开实践。大家可以参考 Spring Cloud Alibaba 文档 来进行接入和配置。

如何选择流控降级组件

讲到这里,大家可能会有疑问:Sentinel 和其它同类产品(如 Hystrix)相比有什么优缺点?是否有必要迁移到 Sentinel?如何快速迁移?以下是 Sentinel 与其它 fault-tolerance 组件的对比:


Sentinel Hystrix resilience4j
隔离策略 信号量隔离(并发控制) 线程池隔离/信号量隔离 信号量隔离
熔断降级策略 基于慢调用比例、异常比例、异常数 基于异常比例 基于异常比例、响应时间
实时统计实现 滑动窗口(LeapArray) 滑动窗口(基于 RxJava) Ring Bit Buffer
动态规则配置 支持多种数据源 支持多种数据源 有限支持
扩展性 多个扩展点 插件的形式 接口的形式
基于注解的支持 支持 支持 支持
限流 基于 QPS,支持基于调用关系的限流 有限的支持 Rate Limiter
流量整形 支持预热模式与匀速排队控制效果 不支持 简单的 Rate Limiter 模式
系统自适应保护 支持 不支持 不支持
多语言支持 Java/Go/C++ Java Java
Service Mesh 支持 支持 Envoy/Istio 不支持 不支持
控制台 提供开箱即用的控制台,可配置规则、实时监控、机器发现等 简单的监控查看 不提供控制台,可对接其它监控系统

总结

通过本教程,我们了解了流控降级作为高可用防护手段的重要性,了解了 Sentinel 的核心特性和原理,并通过动手实践学习了如何快速接入 SCA Sentinel 来为微服务进行流控降级。Sentinel 还有着非常多的高级特性等着大家去发掘,如热点防护、集群流控等,大家可以参考 Sentinel 官方文档来了解更多的特性和场景。

那么是不是服务的量级很小就不用进行限流防护了呢?是不是微服务的架构比较简单就不用引入熔断保护机制了呢?其实,这与请求的量级、架构的复杂程度无关。很多时候,可能正是一个非常边缘的服务出现故障而导致整体业务受影响,造成巨大损失。我们需要具有面向失败设计的意识,在平时就做好容量规划和强弱依赖的梳理,合理地配置流控降级规则,做好事前防护,而不是在线上出现问题以后再进行补救。


目录
相关文章
|
3天前
|
监控 安全 Java
Spring cloud原理详解
Spring cloud原理详解
14 0
|
7天前
|
消息中间件 负载均衡 Java
【Spring Cloud 初探幽】
【Spring Cloud 初探幽】
14 1
|
9天前
|
Java 开发者 微服务
Spring Cloud原理详解
【5月更文挑战第4天】Spring Cloud是Spring生态系统中的微服务框架,包含配置管理、服务发现、断路器、API网关等工具,简化分布式系统开发。核心组件如Eureka(服务发现)、Config Server(配置中心)、Ribbon(负载均衡)、Hystrix(断路器)、Zuul(API网关)等。本文讨论了Spring Cloud的基本概念、核心组件、常见问题及解决策略,并提供代码示例,帮助开发者更好地理解和实践微服务架构。此外,还涵盖了服务通信方式、安全性、性能优化、自动化部署、服务网格和无服务器架构的融合等话题,揭示了微服务架构的未来趋势。
32 6
|
13天前
|
JSON Java Apache
Spring Cloud Feign 使用Apache的HTTP Client替换Feign原生httpclient
Spring Cloud Feign 使用Apache的HTTP Client替换Feign原生httpclient
|
13天前
|
负载均衡 Java 开发者
Spring Cloud:一文读懂其原理与架构
Spring Cloud 是一套微服务解决方案,它整合了Netflix公司的多个开源框架,简化了分布式系统开发。Spring Cloud 提供了服务注册与发现、配置中心、消息总线、负载均衡、熔断机制等工具,让开发者可以快速地构建一些常见的微服务架构。
|
15天前
|
消息中间件 Java RocketMQ
Spring Cloud RocketMQ:构建可靠消息驱动的微服务架构
【4月更文挑战第28天】消息队列在微服务架构中扮演着至关重要的角色,能够实现服务之间的解耦、异步通信以及数据分发。Spring Cloud RocketMQ作为Apache RocketMQ的Spring Cloud集成,为微服务架构提供了可靠的消息传输机制。
28 1
|
15天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo: 微服务通信的高效解决方案
【4月更文挑战第28天】在微服务架构的发展中,服务间的高效通信至关重要。Spring Cloud Dubbo 提供了一种基于 RPC 的通信方式,使得服务间的调用就像本地方法调用一样简单。本篇博客将探讨 Spring Cloud Dubbo 的核心概念,并通过具体实例展示其在项目中的实战应用。
15 2
|
15天前
|
监控 Java Sentinel
Spring Cloud Sentinel:概念与实战应用
【4月更文挑战第28天】在分布式微服务架构中,确保系统的稳定性和可靠性至关重要。Spring Cloud Sentinel 为微服务提供流量控制、熔断降级和系统负载保护,有效预防服务雪崩。本篇博客深入探讨 Spring Cloud Sentinel 的核心概念,并通过实际案例展示其在项目中的应用。
24 0
|
15天前
|
Cloud Native Java Nacos
Spring Cloud Nacos:概念与实战应用
【4月更文挑战第28天】Spring Cloud Nacos 是一个基于 Spring Cloud 构建的服务发现和配置管理工具,适用于微服务架构。Nacos 提供了动态服务发现、服务配置、服务元数据及流量管理等功能,帮助开发者构建云原生应用。
21 0