文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用

2023-09-02 14:53

关注

前言

在这里插入图片描述

本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识,具体内容包括分布式系统存在的问题分布式系统问题的解决方案Sentinel介绍Sentinel快速开始(包括:API实现Sentinel资源保护@SentinelResource注解实现资源保护),Sentinel控制台Spring Cloud Alibaba整合Sentinel 等进行详尽介绍~

不积跬步,无以至千里;不积小流,无以成江海。每天进步一点点,在成为强者的路上,小新与大家共同成长!

📌博主主页:小新要变强 的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)

↩️本文上接:Spring Cloud Alibaba全家桶(五)——微服务组件Nacos配置中心


目录

微服务组件Sentinel介绍与使用

在这里插入图片描述

一、分布式系统存在的问题

分布式系统可能会遇到的问题:服务的可用性问题

在这里插入图片描述

服务的可用性场景:在一个高度服务化的系统中,我们实现的一个业务逻辑通常会依赖多个服务, 如图所示:

在这里插入图片描述

如果其中的下单服务不可用,就会出现线程池里所有线程都因等待响应而被阻塞,从而造成整个服务链路不可用,进而导致整个系统的服务雪崩,如图所示:

在这里插入图片描述

服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应导致服务不可用的原因:

在这里插入图片描述

在服务提供者不可用的时候,会出现大量重试的情况:用户重试、代码逻辑重试,这些重试 终导致:进一步加大请求流量。所以归根结底导致雪崩效应的 根本原因是:大量请求线程同步等待造成的资源耗尽。当服务调用者使用同步调用时, 会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。

二、分布式系统问题的解决方案

解决问题的关键就是提高系统的稳定性、恢复性。

在这里插入图片描述

常见的容错机制:

原理:用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,则会进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。

隔离前:

在这里插入图片描述
在这里插入图片描述

隔离后:

在这里插入图片描述

信号隔离:信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离 大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请, 如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。信号量的大小可以动态调整, 线程池大小不可以。

远程服务不稳定或网络抖动时暂时关闭,就叫服务熔断。

现实世界的断路器大家肯定都很了解,断路器实时监控电路的情况,如果发现电路电流异常,就会跳闸,从而防止电路被烧毁。

软件世界的断路器可以这样理解:实时监测应用,如果发现在一定时间内失败次数/失败率达到一定阈值,就“跳闸”,断路器打开——此时,请求直接返回,而不去调用原本调用的逻辑。跳闸一段时间后(例如10秒),断路器会进入半开状态,这是一个瞬间态,此时允许一次请求调用该调的逻辑,如果成功,则断路器关闭,应用正常调用;如果调用依然不成功,断路器继续回到打开状态,过段时间再进入半开状态尝试——通过”跳闸“,应用可以保护自己,而且避免浪费资源;而通过半开的设计,可实现应用的“自我修复“。

所以,同样的道理,当依赖的服务有大量超时时,在让新的请求去访问根本没有意义,只会无畏的消耗现有资源。比如我们设置了超时时间为1s,如果短时间内有大量请求在1s内都得不到响应,就意味着这个服务出现了异常,此时就没有必要再让其他的请求去访问这个依赖了,这个时候就应该使用断路器避免资源浪费。

在这里插入图片描述

服务降级有服务熔断,必然要有服务降级。

所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。 例如:(备用接口/缓存/mock数据) 。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。

在这里插入图片描述

在这里插入图片描述

三、Sentinel介绍

Sentinel:——分布式系统的流量防卫兵。

在这里插入图片描述

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

源码地址:https://github.com/alibaba/Sentinel

官方文档:https://github.com/alibaba/Sentinel/wiki

Sentinel具有以下特征:

阿里云提供了 企业级的 Sentinel 服务,应用高可用服务 AHAS。

在这里插入图片描述

Sentinel和Hystrix对比:
在这里插入图片描述

四、Sentinel快速开始

https://github.com/alibaba/Sentinel/wiki/如何使用

使用 Sentinel 来进行资源保护,主要分为几个步骤:

Entry entry = null;// 务必保证 finally 会被执行try {  // 资源名可使用任意有业务语义的字符串,注意数目不能太多(超过 1K),超出几千请作为参数传入而不要直接作为资源名  // EntryType 代表流量类型(inbound/outbound),其中系统规则只对 IN 类型的埋点生效  entry = SphU.entry("自定义资源名");  // 被保护的业务逻辑  // do something...} catch (BlockException ex) {  // 资源访问阻止,被限流或被降级  // 进行相应的处理操作} catch (Exception ex) {  // 若需要配置降级规则,需要通过这种方式记录业务异常  Tracer.traceEntry(ex, entry);} finally {  // 务必保证 exit,务必保证每个 entry 与 exit 配对  if (entry != null) {    entry.exit();  }}

1️⃣API实现Sentinel资源保护

🍀(1)引入依赖

<dependency>  <groupId>com.alibaba.cspgroupId>  <artifactId>sentinel‐coreartifactId>  <version>1.8.0version>dependency>

🍀(2)编写测试逻辑

@RestController @slf4jpublic class Hellocontroller {  private static final String RESOURCE_NAAE = "hello" ;    RequestMapping(walue = "/hello")  public String hello() {    Entry entry = null;    try {      //资源名可使用任意有业务语义的字符中,比如方法名、接口名或其它可唯一标识的字符串。      entry = SphU.entry(RESOURCE_NAME);      //被保护的业务逻辑      String str = "hello world";      log .info("====="+str);      return str;    } catch (BlockException e1){      // 资源访问阻止,被限流或被降级      // 进行相应的处理操作      log.info("block!");    } catch (Exception ex) {      // 若需要配置降级规则,需要通过这种方式记录业务异常      Tracer.traceEntry(ex, entry);    } finally {      if(entry != null){        entry.exit();      }    }    return null;  }      @PostConstruct  private static void initFlowRules() {    List<FlowRule> rules = new ArrayList<>();    FlowRule rule = new FlowaRule();    // 设置受保护的资源    rule.setResource(RESOURCE_NAME);  }}

🍀(3)测试效果

在这里插入图片描述

🍀(4)缺点

2️⃣@SentinelResource注解实现资源保护

@SentinelResource 注解用来标识资源是否被限流、降级。

blockHandler: 定义当资源内部发生了BlockException应该进入的方法(捕获的是Sentinel定义的异常)。

fallback: 定义的是资源内部发生了Throwable应该进入的方法。

exceptionsToIgnore:配置fallback可以忽略的异常。

源码入口:com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect。

🍀(1)引入依赖

<dependency>  <groupId>com.alibaba.cspgroupId>  <artifactId>sentinel‐annotation‐aspectjartifactId>  <version>1.8.0version>dependency>

🍀(2)配置切面支持

@Configurationpublic class SentinelAspectConfiguration {  @Bean  public SentinelResourceAspect sentinelResourceAspect() {    return new SentinelResourceAspect();  }}

🍀(3)UserController中编写测试逻辑,添加@SentinelResource,并配置blockHandler和fallback

@RequestMapping(value = "/findOrderByUserId/{id}")@SentinelResource(value = "findOrderByUserId",fallback = "fallback",fallbackClass = ExceptionUtil.class,blockHandler = "handleException",blockHandlerClass = ExceptionUtil.class)public R findOrderByUserId(@PathVariable("id") Integer id) {  //ribbon实现  String url = "http://mall‐order/order/findOrderByUserId/"+id;  R result = restTemplate.getForObject(url,R.class);  if(id==4){    throw new IllegalArgumentException("非法参数异常");  }  return result;}

🍀(4)编写ExceptionUtil,注意如果指定了class,方法必须是static方法

public class ExceptionUtil {  public static R fallback(Integer id,Throwable e){    return R.error(2,"===被异常降级啦===");  }  public static R handleException(Integer id, BlockException e){    return R.error(2,"===被限流啦===");  }}

🍀(5)流控规则设置可以通过Sentinel dashboard配置

客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。

<dependency>  <groupId>com.alibaba.cspgroupId>  <artifactId>sentinel‐transport‐simple‐httpartifactId>  <version>1.8.0version>dependency>
 ‐Dcsp.sentinel.dashboard.server=consoleIp:port

五、Sentinel控制台

下载控制台 jar 包并在本地启动:可以参见此处文档https://github.com/alibaba/Sentinel/releases

#启动控制台命令java ‐jar sentinel‐dashboard‐1.8.0.jar

用户可以通过如下参数进行配置:

java ­Dserver.port=8858 ­Dsentinel.dashboard.auth.username=xushu ­Dsentinel.dashboard.auth.password=123456 ­jar sentineldashboard­1.8.0.jar

为了方便快捷启动可以在桌面创建.bat文件:

java ‐Dserver.port=8858 ‐Dsentinel.dashboard.auth.username=xushu ‐Dsentinel.dashboard.auth.password=123456 ‐jar D:\server\sentinel‐dashboard‐1.8.0.jarpause

访问http://localhost:8080/ ,默认用户名密码: sentinel/sentinel

在这里插入图片描述

Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包,所以要确保客户端有访问量;

在这里插入图片描述

六、Spring Cloud Alibaba整合Sentinel

🍀(1)引入依赖

<dependency>  <groupId>com.alibaba.cloudgroupId>  <artifactId>spring‐cloud‐starter‐alibaba‐sentinelartifactId>dependency>

🍀(2)添加yml配置,为微服务设置sentinel控制台地址添加Sentinel后,需要暴露/actuator/sentinel端点,而Springboot默认是没有暴露该端点的,所以需要设置,测试
http://localhost:8800/actuator/sentinel

server:  port: 8800spring:  application:    name: mall‐user‐sentinel‐demo  cloud:    nacos:      discovery:        server‐addr: 127.0.0.1:8848  sentinel:    transport:      # 添加sentinel的控制台地址      dashboard: 127.0.0.1:8080      # 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer      # port: 8719

🍀(3)在sentinel控制台中设置流控规则

🍀(4)测试

因为QPS是1,所以1秒内多次访问会出现如下情形:

在这里插入图片描述
在这里插入图片描述

访问http://localhost:8800/actuator/sentinel, 可以查看flowRules。

在这里插入图片描述

🍀(5)微服务和Sentinel Dashboard通信原理

Sentinel控制台与微服务端之间,实现了一套服务发现机制,集成了Sentinel的微服务都会将元数据传递给Sentinel控制台,架构图如下所示:

在这里插入图片描述

流控针对privoder 熔断降级,针对consumer。


后记

在这里插入图片描述

👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~

来源地址:https://blog.csdn.net/qq_42146402/article/details/129439240

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯