
目录前言一、Sentinel 入门1.1 什么是 Sentinel ?1.2 微服务集成 Sentinel?1.3 安装Sentinel控制台二、Jmeter 压力测试工具2.1 Jmeter 介绍?2.2 Jmeter 安装2.3 接口测试三、Sentinel 使用3.1 限流规则3.1.1 warm up(预热模式)3.1.2?排队等待3.1.3 关联3.1.4 链路3.2 熔断规则3.3 服务降级* *前言–在微服务架构中根据业务来拆分成一个个的服务服务与服务之间可以通过RPC相互调用。为了保证其高可用单个服务通常会集群部署。由于网络原因或者自身的原因服务并不能保证 100% 可用第一个任务没执行完第二又进来…如果单个服务出现问题调用这个服务就会出现线程阻塞此时若有大量的请求涌入Servlet容器的线程资源有限会被消耗完毕导致服务瘫痪。服务与服务之间的依赖性故障会传播会对整个微服务系统造成灾难性的严重后果这就是服务故障的“雪崩”效应。为了解决这个问题业界提出了熔断器模型。一、Sentinel 入门-------------### 1.1 什么是 SentinelSentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。Sentinel 具有以下特征:**丰富的应用场景**Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景, 例如秒杀即 突发流量控制在系统容量可以承受的范围、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。 * **完备的实时监控**Sentinel 提供了实时的监控功能。通过控制台可以看到接入应用的单台机器秒 级数据, 甚至 500 台以下规模的集群的汇总运行情况。 * **广泛的开源生态**Sentinel 提供开箱即用的与其它开源框架/库的整合模块, 例如与 Spring Cloud、Dubbo、gRPC 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。 * **完善的 SPI 扩展点*Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。Sentinel 分为两个部分:**核心库Java 客户端**不依赖任何框架/库,能够运行于所有 Java 运行时环境同时对 Dubbo / Spring Cloud 等框架也有较好的支持。 * **控制台Dashboard**基于 Spring Boot 开发打包后可以直接运行不需要额外的 Tomcat 等 应用容器。 ### 1.2 微服务集成 Sentinel为微服务集成Sentinel非常简单, 只需要加入Sentinel的依赖即可 在生产者模块(basketball)的pom.xml中加入下面依赖 com.alibaba.cloud spring-cloud-starter-alibaba-sentinel ### 1.3 安装Sentinel控制台Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能。**1、**下载jar包,解压到文件夹 ??https://github.com/alibaba/Sentinel/releases**2、**启动控制台 # 直接使用jar命令启动项目(控制台本身是一个SpringBoot项目) java -Dserver.port9999 -Dcsp.sentinel.dashboard.serverlocalhost:9999 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.4.jar #参考1 java -jar sentinel-dashboard-1.8.4.jar --server.port8080 #参考2 java -Dserver.port8080 -Dcsp.sentinel.dashboard.serverlocalhost:8080 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.4.jar**3、添加配置在服务里面加入有关控制台的配置 #sentinel流控 sentinel: transport: port: 8719 dashboard: localhost:9999 #提前加载开关 eager: true4、**通过浏览器访问localhost:9999进入控制台 ( 默认用户名密码是 sentinel/sentinel )控制台的使用原理 Sentinel的控制台其实就是一个SpringBoot编写的程序。我们需要将我们的微服务程序注册到控制台上,即在微服务中指定控制台的地址, 并且还要开启一个跟控制台传递数据的端口, 控制台也可以通过此端口调用微服务中的监控程序获取微服务的各种信息。 二、Jmeter 压力测试工具---------------### 2.1 Jmeter 介绍Apache JMeter 是 Apache 组织基于Java开发的压力测试工具用于对软件做压力测试。Jmeter主要元件1. **测试计划**是使用 JMeter 进行测试的起点它是其它 JMeter测试元件的容器2. **线程组**代表一定数量的用户它可以用来模拟用户并发发送请求。实际的请求内容在Sampler中定义它被线程组包含。3. **配置元件**维护Sampler需要的配置信息并根据实际的需要修改请求的内容。4. *前置处理器负责在请求之前工作常用来修改请求的设置5.定时器负责定义请求之间的延迟间隔。6.取样器(Sampler)是性能测试中向服务器发送请求记录响应信息、响应时间的最小单元如HTTP Request Sampler、FTP Request Sample、TCP Request Sample、JDBC Request Sampler等每一种不同类型的sampler 可以根据设置的参数向服务器发出不同类型的请求。7.后置处理器负责在请求之后工作常用获取返回的值。8.断言用来判断请求响应的结果是否如用户所期望的。9.监听器负责收集测试结果同时确定结果显示的方式。10.逻辑控制器可以自定义JMeter发送请求的行为逻辑它与Sampler结合使用可以模拟复杂的请求序列。### 2.2 Jmeter 安装下载地址Apache JMeter - Apache JMeter?解压即可用打开bin目录下的jmeter.bat进行启动启动后自动进入该页面中文设置、大小、外观### 2.3 接口测试1、添加线程组2、添加取样器3、添加监听器-察看结果树三、Sentinel 使用-------------### 3.1 限流规则 首先了解一下高并发性能指标 *QPS每秒查询 Queries Per Second是衡量信息检索系统例如搜索引擎或数据库在一秒钟内接收到的搜索流量的一种常见度量。该术语在任何请求-响应系统中都得到更广泛的使用更正确地称为每秒请求数RPSRequest Per Second。 *TPS每秒事务 Transactions Per Second的缩写也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户端向服务器发送请求然后服务器做出响应的过程。客户端在发送请求时开始计时收到服务器响应后结束计时以此来计算使用的时间和完成的事务个数。 *RT响应时间 执行一个请求从开始到最后收到响应数据所花费的总体时间即从客户端发起请求到收到服务器响应结果的时间。该请求可以是任何东西从内存获取磁盘IO复杂的数据库查询或加载完整的网页。 *Concurrency并发数 并发数是指系统同时能处理的请求数量这个也反应了系统的负载能力。 并发意味着可以同时进行多个处理。并发在现代编程中无处不在网络中有多台计算机同时存在一台计算机上同时运行着多个应用程序。 *吞吐量 系统的吞吐量承压能力和处理对CPU的消耗、外部接口、IO等因素紧密关联。单个处理请求对CPU消耗越高外部系统接口、IO速度越慢系统吞吐能力越低反之越高。流控效果是指请求达到流控阈值时应该采取的措施包括三种1.快速失败达到阈值后新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。2.warm up预热模式对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化从一个较小值逐渐增加到最大阈值。3.排队等待让所有的请求按照先后次序排队执行两个请求的间隔不能小于指定时长####3.1.1 warm up(预热模式)warm up也叫预热模式是应对服务冷启动的一种方案。 请求阈值初始值是threshold / coldFactor持续指定时长后逐渐提高到threshold值。而coldFactor的默认值是3 大白话来讲刚开始把 阈值调低不要让过多的请求访问服务器导致冲垮服务器先让服务器一点一点处理再慢慢加量。经典的例子一个好久没运动的人你刚开始让他跑10圈他可能会累死但是你给他一个预热时间比如 第一天跑 2圈第三天跑 3 圈第四天跑4圈以此类推…****例如我设置QPS的threshold为10预热时间为5秒那么初始阈值就是 10 / 3 也就是3。请求到达阈值时就会等5秒慢慢升高阈值Jmeter 设置线程组如图我设置了一秒执行一次总共十次。第一次阈值是3…慢慢变多#### 3.1.2排队等待当请求超过QPS阈值时快速失败和warm up 会拒绝新的请求并抛出异常。而排队等待则是让所有请求进入一个队列中然后按照阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成如果请求预期的等待时间超出最大时长则会被拒绝。测试#### 3.1.3 关联当关联的资源达到阈值的时候就限流自己。eg当与/chang关联的资源/tiao达到阈值后就限流/chang自己当执行/tiao接口到达了阈值时/chang才能执行#### 3.1.4 链路链路流控指针对指定接口进行限流一般用在针对访问比较多的接口方法进行限流这里做了一个简单的示例配置热点接口必须使用SentinelResource声明资源名****代码示例package com.example.basketball.controller; import com.alibaba.csp.sentinel.annotation.SentinelResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RestController public class TestController { Autowired private OrderServiceImpl orderService; RequestMapping(“/chang”) public String chang() { orderService.message(); return “??”; } RequestMapping(“/tiao”) public String tiao() { orderService.message(); return “??”; } Service public class OrderServiceImpl { SentinelResource(“message”) public void message() { System.out.println(“kun”); } } }添加yml配置添加链路给/chang 限流### 3.2 熔断规则Sentinel 提供了三种主要的熔断策略用于在系统遇到异常情况时保护服务和资源。这些熔断策略分别是1、慢调用比例 (Slow Request Ratio)这种策略是基于调用响应时间来进行熔断的。当资源的每个请求的平均响应时间超过预设的阈值并且在一个统计窗口期内慢调用的比例超过设定的比例例如20%系统就会触发熔断操作。熔断条件通常包括最小请求数防止请求量过小导致误熔断和慢调用比例阈值。这种策略适用于响应时间敏感的服务可以有效防止因为部分慢请求导致的系统雪崩。 1.**调用**一个请求发送到服务器服务器给与响应一个响应就是一个调用。 2.RT响应时间指执行一个请求从开始到最后收到响应数据所花费的总体时间。 3.**慢调用**当调用的时间响应的实际时间设置的RT的时这个调用叫做慢调用。 4.*慢调用比例在所以调用中慢调用占有实际的比例 慢调用次数 / 调用次数 5.比例阈值自己设定的 慢调用次数 / 调用次数 比例阈值 统计时长与最小请求数 这两个参数的关系在于熔断的触发不仅依赖于异常比例或慢调用比例是否超过阈值还依赖于在统计时长内是否有足够的请求量即是否达到最小请求数来保证统计结果的可靠性。如果统计时长内的请求量没有达到最小请求数即使异常比例或慢调用比例超过了阈值熔断器也不会触发因为样本量太小可能无法代表系统的真实状态。 上面的熔断规则表示说 访问/chang资源时如果在1000毫秒内请求数量超过5并且这些数量中超过400毫秒的请求数量的比例超过0.2则熔断5秒5秒后进入半开状态如果半开状态中有一个请求小于400毫秒则取消熔断否则继续熔断。案例代码RequestMapping(“/message2”) public String message2() { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } return “message2”; }2、异常比例 (Error Ratio)异常比例策略是基于异常发生的比例来进行熔断的。当资源在一个统计窗口期内的异常比例超过预设的阈值例如20%系统就会触发熔断。这种策略通常结合最小请求量来使用以避免因为样本量太小而误触发熔断。这种策略适用于那些对异常率敏感的服务可以在异常率升高时及时进行熔断保护系统。第1步: 首先模拟一个异常第2步: 设置异常比例大于0.2 int i 0; RequestMapping(“/message3”) public String message3() { i; //异常比例为0.333 if (i % 3 0){ throw new RuntimeException(); } return “message3”; }3、异常数 (Error Count)异常数策略是根据一定时间窗口内的异常总数来触发熔断。当在统计窗口期内的异常总数超过预设的阈值例如20个无论请求总数多少都会触发熔断。这种策略不依赖于请求总数而是直接关注异常总量。适用于那些异常数绝对值更重要的场景比如一些关键资源或操作一旦异常数量超过阈值立即熔断以防止系统进一步恶化。这些熔断策略可以根据实际业务和服务特性进行选择和配置。通过合理的熔断策略Sentinel 能有效地防止服务因过高的负载或错误而变得不稳定保护系统免受进一步的损害。### 3.3 服务降级Feign整合Sentinel第1步: 引入sentinel的依赖 com.alibaba.cloud spring-cloud-starter-alibaba-sentinel 第2步: 在配置文件中开启Feign对Sentinel的支持 server: port: 8081 spring: cloud: nacos: server-addr: localhost:8848 #sentinel流控 sentinel: transport: port: 8719 dashboard: localhost:9999 #提前加载开关 eager: true application: name: ikun # 开启feign对sentinel的支持 feign: sentinel: enabled: true第3步: 创建容错类 package com.example.ikun.service.impl; import com.example.ikun.serice.FeginKunService; import org.springframework.stereotype.Component; /* 容错类要求必须实现被容错的接口,并为每个方法实现容错方案 * author * create 2024-01-12 0:44/ Component public class FeginKunServiceImpl implements FeginKunService { Override public String getByPath(String account) { /* 解决方案 * … */ return “嘿嘿嘿”; } } 第4步: 为被容器的接口指定容错类 package com.example.ikun.service; import com.example.ikun.serice.impl.FeginKunServiceImpl; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; /* 连接生产者 Controller * * author * create 2024-01-06 15:40/ FeignClient(value “basketball”, fallback FeginKunServiceImpl.class) //连接服务器名称 public interface FeginKunService { RequestMapping(“/kun/{account}”) public String getByPath(PathVariable(value “account”) String account); } 第五步编写controller接口 package com.example.ikun.controller; import com.example.ikun.service.FeginKunService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RestController public class TestController { Autowired private FeginKunService kunService; RequestMapping(“/play01”) public String play() { return kunService.getByPath(“姬霓太美”); } } 第六步 package com.example.ikun; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; SpringBootApplication EnableDiscoveryClient //开启服务发现 EnableFeignClients(basePackages “com.example.ikun.serice”) //开启Feigin远程 public class IkunApplication { public static void main(String[] args) { SpringApplication.run(IkunApplication.class, args); } } **测试***启动两个服务调用远程basketball服务执行service接口方法将basketball服务关闭 将调用容错解决方案。