高并发解决方案:Sentinel的流量控制、熔断与OpenFeign整合实战

embedded/2024/9/23 10:20:00/

🚀 作者 :“二当家-小D”
🚀 博主简介:⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人,8年开发架构经验,精通java,擅长分布式高并发架构,自动化压力测试,微服务容器化k8s等
🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬
🍅文末获取源码联系 配套笔记打包🍅

🔗上一篇文章传送门:快速入门SpringCloudAlibaba实战篇【SpringBoot3.x + JDK17】!

目录

    • 一、高并发下的微服务架构存在的问题和解决方案
      • 1. 海量请求下的微服务架构存在的问题
      • 2. 面向失败编程-微服务架构容错方案介绍
      • 3. 分布式系统的流量防卫兵-Sentinel介绍
      • 4. 流量防卫兵-Sentinel依赖引入和控制台搭建
      • 5. AliababCloud微服务整合Sentinel限流配置实战
    • 二、玩转Sentinel多种流控规则和实战
      • 1. 玩转Sentinel流量控制功能
      • 2. 基于并发线程数进行限流配置实操
      • 3. 流控规则效果-直接拒绝-冷启动预热-匀速排队讲解
      • 4. Sentinel-微服务高可用利器-熔断降级规则讲解
      • 5. Sentinel的熔断状态和恢复讲解
      • 6. Sentinel整合AlibabaCloud微服务熔断实操
    • 三、玩转Sentinel自定义异常-整合Open-Feign
      • 1. AlibabaCloud版本升级-自定义降级异常不向下兼容的坑
      • 2. Sentinel自定义降级异常数据开发实战
      • 3. Sentinel整合OpenFeign配置实战
    • 结束语

一、高并发下的微服务架构存在的问题和解决方案

1. 海量请求下的微服务架构存在的问题

简介:高并发下的微服务存在的问题

  • 高并发下存在的问题

    • 微服务拆分多个系统,服务之间互相依赖,可能会由于系统负载过高,突发流量或者网络等各种异常情况 导致服务不可用。
  • 核心思想-面向失败编程

    • 不要外界影响
    • 不被请求拖垮
      • 上游服务
      • 下游服务

2. 面向失败编程-微服务架构容错方案介绍

简介:高并发下的微服务容错方案

  • 限流

  • 漏斗,不管流量多大,均匀的流入容器,令牌桶算法,漏桶算法

    image-20200908182543365

  • 熔断:

    • 保险丝,熔断服务,为了防止整个系统故障,包含当前和下游服务 下单服务 -》商品服务-》用户服务 -》(出现异常-》熔断风控服务
  • 降级:

    • 抛弃一些非核心的接口和数据,返回兜底数据 旅行箱的例子:只带核心的物品,抛弃非核心的,等有条件的时候再去携带这些物品
  • 隔离:

    • 服务和资源互相隔离,比如网络资源,机器资源,线程资源等,不会因为某个服务的资源不足而抢占其他服务的资源
  • 熔断和降级互相交集

    • 相同点:
      • 从可用性和可靠性触发,为了防止系统崩溃
      • 最终让用户体验到的是某些功能暂时不能用
    • 不同点
      • 服务熔断一般是下游服务故障导致的,而服务降级一般是从整体系统负荷考虑,由调用方控制
  • 想进行微服务的容错,业界目前有Sentinel、Hystrix,相对于AlibabaCloud而言,Sentinel是最好的搭配

    image-20200908195729987

3. 分布式系统的流量防卫兵-Sentinel介绍

简介:介绍什么是分布式系统的流量防卫兵Sentinel

  • 什么是Sentinel
    • 阿里巴巴开源的分布式系统流控工具
    • 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性
    • 丰富的应用场景:消息削峰填谷、集群流量控制、实时熔断下游不可用应用等
    • 完备的实时监控:Sentinel 同时提供实时的监控功能
    • 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合
  • 官网:介绍 · alibaba/Sentinel Wiki
  • Sentinel版本:1.8.6
  • 核心概念:
    • 资源:是 Sentinel 中的核心概念之一,可以是java程序中任何内容,可以是服务或者方法甚至代码,总结起来就是我们要保护的东西
    • 规则:定义怎样的方式保护资源,主要包括流控规则、熔断降级规则等

Sentinel-features-overview

4. 流量防卫兵-Sentinel依赖引入和控制台搭建

简介:微服务引入Sentinel和控制台搭建

  • Sentinel 分为两个部分

    • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo、Spring Cloud 等框架也有较好的支持。
    • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
  • 微服务引入Sentinel依赖

     <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  • Sentinel控制台搭建

  • 文档:控制台 · alibaba/Sentinel Wiki

  • 控制台包含如下功能:

    • 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
    • 监控 (单机和集群聚合)通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
    • 规则管理和推送:统一管理推送规则。
    • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

    注意:Sentinel 控制台目前仅支持单机部署

//启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本,
//-Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080 
//默认用户名和密码都是 sentineljava -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar

在这里插入图片描述

5. AliababCloud微服务整合Sentinel限流配置实战

简介:讲解AliababCloud微服务整合Sentinel限流配置实操

  • 多个微服务接入Sentinel配置

    spring:cloud:sentinel:transport:dashboard: 127.0.0.1:8080 port: 9999 #dashboard: 8080 控制台端口
    #port: 9999 本地启的端口,随机选个不能被占用的,与dashboard进行数据交互,会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互, 若被占用,则开始+1一次扫描
    
  • 微服务注册上去后,由于Sentinel是懒加载模式,所以需要访问微服务后才会在控制台出现

  • 限流配置实操

    • 控制台配置

在这里插入图片描述

  • 浏览器刷新

image-20200908203307475

二、玩转Sentinel多种流控规则和实战

1. 玩转Sentinel流量控制功能

简介:讲Sentinel流量控制详细操作

  • 流量控制(flow control)

    • 原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
  • 两种规则

    • 基于统计并发线程数的流量控制
    并发数控制用于保护业务线程池不被慢调用耗尽Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目)如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。
    
    • 基于统计QPS的流量控制
    当 QPS 超过某个阈值的时候,则采取措施进行流量控制
    
  • 控制面板介绍

    • 资源名:默认是请求路径,可自定义
    • 针对来源:对哪个微服务进行限流,默认是不区分来源,全部限流,这个是针对 区分上游服务进行限流, 比如 视频服务 被 订单服务、用户服务调用,就可以针对来源进行限流

image-20200908210235984

2. 基于并发线程数进行限流配置实操

简介:基于并发线程进行限流配置实操

  • 开发临时接口,方便测试
java">    @RequestMapping("list")public Object list(){try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}Map<String,String> map  = new HashMap<>();map.put("title1","ALibabaCloud微服务专题");map.put("title2","小滴课堂面试专题第一季");return map;}
  • 基于统计并发线程数的流量控制
并发数控制用于保护业务线程池不被慢调用耗尽Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目)如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置
  • 流控规则会下发到微服务,微服务如果重启,则流控规则会消失,可以持久化配置
  • 选择阈值类型 ”线程数“ ,配置是1

在这里插入图片描述

  • 刷新浏览器

3. 流控规则效果-直接拒绝-冷启动预热-匀速排队讲解

简介:基于并发线程进行限流配置实操

  • 流量控制的效果包括以下几种:

    • 直接拒绝:默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝

    • Warm Up:冷启动/预热,如果系统在此之前长期处于空闲的状态,我们希望处理请求的数量是缓步的增多,经过预期的时间以后,到达系统处理请求个数的最大值

    image-20200908212417778

    • 匀速排队:严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法,主要用于处理间隔性突发的流量,如消息队列,想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求

      image

      • 注意:
        • 匀速排队等待策略是 Leaky Bucket 算法结合虚拟队列等待机制实现的。
        • 匀速排队模式暂时不支持 QPS > 1000 的场景
  • 流控文档

    • 流量控制 · alibaba/Sentinel Wiki

4. Sentinel-微服务高可用利器-熔断降级规则讲解

简介:讲解 微服务高可用利器Sentinel熔断降级规则

  • 备注:如果 簇点链路 没数据,刷多几次接口

  • 熔断降级(虽然是两个概念,基本都是互相配合)

    • 对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一
    • 对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩
    • 熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置
  • 什么是Sentinel降级规则

    • 文档:熔断降级 · alibaba/Sentinel Wiki
    • 就是配置一定规则,然后满足之后就对服务进行熔断降级
  • Sentinel 熔断策略

    • 慢调用比例(响应时间): 选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用

      • 比例阈值:修改后不生效-目前已经反馈给官方那边的bug
      • 熔断时长:超过时间后会尝试恢复
      • 最小请求数:熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断
      • 统计时长:用于收集和评估熔断条件的数据时间范围
        在这里插入图片描述
    • 异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断

      • 比例阈值
      • 熔断时长:超过时间后会尝试恢复
      • 最小请求数:熔断触发的最小请求数,请求数小于该值时,即使异常比率超出阈值也不会熔断
      • 统计时长:用于收集和评估熔断条件的数据时间范围
        在这里插入图片描述
    • 异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断

      • 异常数:
      • 熔断时长:超过时间后会尝试恢复
      • 最小请求数:熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断
      • 统计时长:用于收集和评估熔断条件的数据时间范围
        在这里插入图片描述

5. Sentinel的熔断状态和恢复讲解

简介:讲解服务调用常见的熔断状态和恢复

  • 服务熔断一般有三种状态(画图)

    • 熔断关闭(Closed)

      • 服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制
    • 熔断开启(Open)

      • 后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法
    • 半熔断(Half-Open)

      • 所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率

      image-20200909171947975

  • 熔断恢复:

    • 经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态)尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。

    • 如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断状态

6. Sentinel整合AlibabaCloud微服务熔断实操

简介:讲解服务调用熔断例子

  • 修改代码

  • 熔断测试

    java">    int temp = 0;@RequestMapping("list")public Object list(){// try {//     TimeUnit.SECONDS.sleep(3);// } catch (InterruptedException e) {//     e.printStackTrace();// }temp++;if(temp%3 == 0){throw  new RuntimeException();}Map<String,String> map  = new HashMap<>();map.put("title1","ALibabaCloud微服务专题");map.put("title2","小滴课堂面试专题第一季");return map;}
    
  • 浏览器刷新请求
    在这里插入图片描述

三、玩转Sentinel自定义异常-整合Open-Feign

1. AlibabaCloud版本升级-自定义降级异常不向下兼容的坑

简介:讲解Sentinel自定义异常降级-新旧版本差异

  • 默认降级返回数据问题

    • 限流和熔断返回的数据有问题-
    • 微服务交互基本都是json格式,如果让自定义异常信息
  • AlibabCloud版本升级,不兼容问题

    • v2.1.0到v2.2.0后,Sentinel里面依赖进行了改动,且不向下兼容
  • 自定义降级返回数据

    • 【旧版】实现UrlBlockHandler并且重写blocked方法
    @Component
    public class XdclassUrlBlockHandler implements UrlBlockHandler {@Overridepublic void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {//降级业务处理}
    }
    • 【新版】实现BlockExceptionHandler并且重写handle方法
    public class XdclassUrlBlockHandler implements BlockExceptionHandler {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {//降级业务处理}
    }

2. Sentinel自定义降级异常数据开发实战

简介:讲解新版Sentinel自定义异常数据开发实战

  • 异常种类

    FlowException  //限流异常
    DegradeException  //降级异常
    ParamFlowException //参数限流异常
    SystemBlockException //系统负载异常
    AuthorityException //授权异常
    
  • 实现BlockExceptionHandler并且重写handle方法

    java">@Component
    public class XdclassUrlBlockHandler implements BlockExceptionHandler {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {Map<String,Object> backMap=new HashMap<>();if (e instanceof FlowException){backMap.put("code",-1);backMap.put("msg","限流-异常啦");}else if (e instanceof DegradeException){backMap.put("code",-2);backMap.put("msg","降级-异常啦");}else if (e instanceof ParamFlowException){backMap.put("code",-3);backMap.put("msg","热点-异常啦");}else if (e instanceof SystemBlockException){backMap.put("code",-4);backMap.put("msg","系统规则-异常啦");}else if (e instanceof AuthorityException){backMap.put("code",-5);backMap.put("msg","认证-异常啦");}// 设置返回json数据httpServletResponse.setStatus(200);httpServletResponse.setHeader("content-Type","application/json;charset=UTF-8");httpServletResponse.getWriter().write(JSON.toJSONString(backMap));}
    }
    
  • 浏览器刷新请求
    在这里插入图片描述

3. Sentinel整合OpenFeign配置实战

简介:使用Feign整合Sentinel配置实战

  • 整合步骤

    • 加入依赖
    <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    • 开启Feign对Sentinel的支持
    feign:sentinel:enabled: true
    
    • 创建容错类, 实现对应的服务接口, 记得加注解 @Service
    java">@Service
    public class VideoServiceFallback implements VideoService {@Overridepublic Video findById(int videoId) {Video video = new Video();video.setTitle("熔断降级数据");return video;}@Overridepublic Video saveVideo(Video video) {return null;}
    }
    
    • 配置feign容错类
    @FeignClient(value = "xdclass-video-service", fallback = VideoServiceFallback.class)
    
  • 准备 兜底数据

  • 断开视频服务,依旧有返回数据

    在这里插入图片描述

结束语

今天的文章主要从Sentinel的核心概念出发,详细讲解了如何实现限流、熔断和降级策略,以确保系统的稳健运行。通过介绍控制台的建立和配置,以及集成OpenFeign来处理服务间通信的容错,希望能够帮助你理解和应用这些技术以增强你的微服务架构能力。

今天的文章就到这了,关注D哥,下期分享更多关于SpringCloud Alibaba干货内容!

资料获取📚
完整代码和笔记已经准备好,如果有问题,可以在评论区留言讨论💬
原创不易,别忘了点赞👍+收藏⭐哦!
点击下方链接即可获取完整资料压缩包🎁,快来领取吧!↓↓↓↓


http://www.ppmy.cn/embedded/32106.html

相关文章

LLM应用:工作流workflow创建自定义模版使用

参考: https://www.coze.cn/ 本案例是在coze平台上操作的,也有其他工具支持工作流的创建例如dify;也例如图像生成的comfyui工作流工具 创建自定义模版 可以根据自己需求创建自己的工作流工具;本文案例是创建一个联网搜索的LLM应用: 创建工作流页面: https://www.coze.c…

Visual studio调试技巧

Visual studio调试技巧 bug是什么&#xff1f;Debug和ReleaseDebugRelease 如何调试VS调试快捷键调试过程中查看程序信息查看临时变量的值查看内存信息查看调用堆栈查看汇编信息查看寄存器信息 编译常见错误编译型错误链接型错误运行时错误 bug是什么&#xff1f; bug的英文释…

JSON转CSV:使用Java处理复杂数据结构

引言 在数据处理和分析的世界中&#xff0c;经常需要将数据从一种格式转换为另一种更便于处理或分析的格式。本文将详细介绍如何使用Java语言&#xff0c;配合Jackson和Apache Commons CSV库&#xff0c;将嵌套的JSON数据转换成CSV格式。这种技能在数据科学、软件开发和系统集…

Agent AI智能体,塑造智能新纪元

Agent AI智能体&#xff0c;即AI Agent&#xff0c;是指人工智能代理&#xff0c;是一种能够感知环境、进行决策和执行动作的智能实体。它具备通过独立思考、调用工具逐步完成给定目标的能力。与大模型不同&#xff0c;AI Agent的工作仅需给定一个目标&#xff0c;它就能够针对…

「2024年」前端开发常用工具函数总结 TypeScript

前言 在前端开发中&#xff0c;工具函数是提高代码复用率、保持代码整洁和增加开发效率的关键。使用 TypeScript 编写工具函数不仅可以帮助开发者捕捉到更多的类型错误&#xff0c;还可以提供更清晰的代码注释和更智能的代码补全。下面是一些在 TypeScript 中常用的前端开发工…

【前端学习——react文档】学习react文档笔记(持续更新)

React官方文档 我不一定按照文档顺序记录 jsx语法系列 JSX 中通过大括号使用 JavaScript 可以在哪使用大括号 &#xff1f; 用作 JSX 标签内的文本&#xff1a;<h1>{name}s To Do List</h1> 是有效的&#xff0c;但是 <{tag}>Gregorio Y. Zaras To Do Lis…

数据结构—C语言实现双向链表

目录 1.双向带头循环链表 2.自定义头文件&#xff1a; 3.List.cpp 文件 3.1 newnode()函数讲解 3.2 init() 函数 初始化 3.3 pushback()函数 尾插 3.4 pushfront()函数 头插 3.5 popback() 尾删 3.6 popfront() 函数 头删 3.7 insert()函数 在pos之后插入 3.8 popbac…

Electron使用 SQLite

在客户端开发中&#xff0c;无论是 PC 端&#xff0c;还是手机端&#xff0c;为了能够访问离线数据&#xff0c;数据经常需要保存到本地&#xff0c;IndexDB 可以用于存储本地数据&#xff0c;IndexDB 是一个对象存储&#xff0c;数据是以 key:value 的形式进行存储和访问的&am…