SpringCloud Sentinel服务保护详解(请求限流、线程隔离、服务熔断)

 更新时间:2025年05月09日 10:00:08   作者:昊坤说不出的梦  
这篇文章主要介绍了SpringCloud Sentinel服务保护详解(请求限流、线程隔离、服务熔断),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

开发环境

环境:Java 11、MySQL 8.0、OpenFeign、sentinel-dashboard 1.8.6

为什么要保护

微服务在远程调用时,可能存在以下问题:

1. 业务健壮性:

如,购物车服务、商品服务之间互相调用,当一方挂掉,需要做兜底处理从而优化用户体验

假设,查询购物车接口需要调用商品服务,商品服务挂了导致查询失败,但从业务角度为了提高用户体验,即使查询失败,购物车列表也应该展示出来(展示空数据/缓存数据)。而不是丢给用户一堆报错信息

2. 级联失败(雪崩问题):

如,高峰期时查询接口并发高,其他接口并发小;由于高并发接口占用过多的Tomcat连接,可能导致所有接口都延迟变高、长时间阻塞甚至失败。

以此类推,当互相调用的服务间出现问题时,可能导致整个集群都不可用

Sentinel 实现保护

提示:这里可以添加要学的内容

例如:

  1. 搭建 Java 开发环境
  2. 掌握 Java 基本语法
  3. 掌握条件语句
  4. 掌握循环语句

策略1:请求限流

理解:限制/控制接口的请求流量

并发太高是导致服务故障的重要原因。

因此通过限制或控制接口的并发流量,避免服务因流量激增而出现故障。

策略2:线程隔离

理解:提前分配好资源(线程)给业务接口

当一个业务接口响应时间长,而且并发高时,就可能耗尽服务器的线程资源,导致服务内的其它接口受到影响。

因此为了降低/减小这种影响,使用线程隔离,其思想参考舱壁模型

如,查询接口访问频繁,会无休止地占用更多的线程资源,而导致其他业务的线程资源紧张或无法分配。

线程隔离:锁死查询接口20线程,其他业务10线程,就算查询接口并发再高,只给20线程资源去调用,确保了其他业务不被影响。

策略3:服务熔断

理解:对故障/速度慢的接口进行暂时切断,并提供一个友好提示以优化用户体验

服务熔断主要有两点:

  • 编写服务降级逻辑:调用失败后的处理逻辑,可抛出异常/友好提示/默认数据/缓存数据。
  • 异常统计和熔断:统计异常比例,当比例过高表明该接口会影响到其它服务,应该拒绝调用该接口,而是直接走降级逻辑。

Sentinel 流量控制

Sentinel 主要有两部分

  • 核心库(Jar包):直接引入到pom.xml就生效,在项目中可以编程式编写限流、隔离、熔断等规则。
  • 控制台(DashBoard):负责管理推送规则、监控、管理机器信息等。

依赖引入:

 <dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
   <version>2021.0.4.0</version>
 </dependency>

控制台启动:

下载:控制台jar包
启动:java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

配置application.yaml

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8090
      http-method-specify: true # 开启请求方式前缀(为了区分GET/POST/DELETE等请求)

配置策略

细节1:需要触发一次请求才会在Sentinel面板看到该接口的簇点
细节2:默认直接在面板上的配置是临时的,重启服务后配置就清空了

具体的流控规则需要根据业务来进行设置

Sentinel 服务熔断

问题1:当接口触发Sentinel配置的流控规则时,抛出异常,用户体验不佳

解决方案:降级处理,展示空数据/缓存的旧数据

问题2:当A接口需要远程调用B,而B延迟较高,拖慢了A的服务,用户体验差

解决方案:熔断慢接口,直接停止使用B接口,走降级逻辑

本次练习采用的是OpenFeign远程调用,使用远程调用主要有两种方式

  1. 方式一:FallbackClass,无法对远程调用的异常做处理
  2. 方式二:FallbackFactory,可以对远程调用的异常做处理,我们一般选择这种方式。

故使用更为灵活的FallbackFactory

首先配置降级逻辑:返回空集合

@Slf4j
public class ItemClientFallback implements FallbackFactory<ItemClient> {
    @Override
    public ItemClient create(Throwable cause) {
        return new ItemClient() {
            @Override
            public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
                log.error("远程调用ItemClient#queryItemByIds方法出现异常,参数:{}", ids, cause);
                // 查询购物车允许失败,查询失败,返回空集合
                return CollUtils.emptyList();
            }

            @Override
            public void deductStock(List<OrderDetailDTO> items) {
                log.error("扣减商品库存失败!",cause);
                // 库存扣减业务需要触发事务回滚,查询失败,抛出异常
                throw new BizIllegalException(cause);
            }
        };
    }
}

将降级处理逻辑注册成@Bean

 /**
 * Feign配置类
 */
public class DefaultFeignConfig {
    @Bean
    public ItemClientFallback itemClientFallback(){
        return new ItemClientFallback();
    }
}

在远程调用的注解处配置:失败处理逻辑的类

/**
 * 远程调用商品服务
 */
@FeignClient(value = "item-service",fallbackFactory = ItemClientFallback.class)
public interface ItemClient {
...
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringAop中AspectJ框架的切入点表达式

    SpringAop中AspectJ框架的切入点表达式

    这篇文章主要介绍了SpringAop中AspectJ框架的切入点表达式,AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持,@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面,需要的朋友可以参考下
    2023-08-08
  • 深入理解SpringMVC中央调度器DispatcherServlet

    深入理解SpringMVC中央调度器DispatcherServlet

    这篇文章主要介绍了SpringMVC核心之中央调度器DispatcherServlet的相关知识,包括SpringMVC请求处理过程及SrpingMVC容器和spring IOC容器关系,需要的朋友可以参考下
    2022-05-05
  • Spring启动流程源码解析

    Spring启动流程源码解析

    这篇文章主要介绍了Spring启动流程源码解析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Java实现贪吃蛇游戏

    Java实现贪吃蛇游戏

    这篇文章主要为大家详细介绍了Java实现贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • Spring AI与DeepSeek实战一之快速打造智能对话应用

    Spring AI与DeepSeek实战一之快速打造智能对话应用

    本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭建、配置API-KEY、创建ChatClient对象、创建对话接口、切换模型、使用prompt模板、流式对话等,感兴趣的朋友一起看看吧
    2025-03-03
  • Java中的信息摘要算法MessageDigest类用法详解

    Java中的信息摘要算法MessageDigest类用法详解

    这篇文章主要介绍了Java中的信息摘要算法MessageDigest类用法详解,java.security.MessageDigest类为应用程序提供信息摘要算法的功能,如MD5或SHA-1或SHA-256算法,信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值,需要的朋友可以参考下
    2024-01-01
  • 关于shiro中部分SpringCache失效问题的解决方法

    关于shiro中部分SpringCache失效问题的解决方法

    这篇文章主要给大家介绍了关于shiro中部分SpringCache失效问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • Java private修饰符失效的原因

    Java private修饰符失效的原因

    在Java编程里,使用private关键字修饰了一个成员,只有成员内部可以访问,其余成员都不可访问,今天说明一下private功能失效的问题。
    2020-10-10
  • FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换操作

    FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换操作

    这篇文章主要介绍了FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • Java的线程池ThreadPoolExecutor及多种线程池实现详解

    Java的线程池ThreadPoolExecutor及多种线程池实现详解

    这篇文章主要介绍了Java的线程池ThreadPoolExecutor及多种线程池实现详解,ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量,之所以将信息存储在一个变量中,是为了保证原子性,需要的朋友可以参考下
    2024-01-01

最新评论