1,工作原理

2,常见规则

流量控制(FlowRule)

1,阈值类型设置如下

单机均摊:每个机器均摊,比如阈值填5,三个机器,就个机器都可以有5个

总体阈值:所有机器总阈值,比如阈值填5,三个机器,总共进5个请求

2,流控模式设置如下

只有流控效果是快速失败才支持调整流控模式 

直接:默认,限制请求直接对资源进行限制

关联:数据库读写,当写比较大时,限制读的限流,达到优先写

关联测试案例

先添加俩方法,一个读一个写,在orderControoler类中

  @GetMapping("/readDb")public String readDb(){return "readDb.....";}@GetMapping("/writeDb")public String writeDb(){return "writeDb.....";}

然后调用俩接口,在dashborard中查看俩资源,进行如下设置,即在读的资源下设置限流,流控模式为关联,关联资源为writeDb,则可实现写量过大时,访问读会被限流(设置好之后,测试先访问readDb,正常访问也没被限流,但再访问writeDb的时候,疯狂刷新,再回去访问readDb则readDb就会被限流)

链路: 根据不同的调用链,来控制不同调用链

链路测试案例

添加一个seckill方法,同createOrder,在orderController类中

   @GetMapping("/create")public Order createOrder(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId){Order order = orderService.createOrder(userId,productId);return order;}@GetMapping("/seckill")public Order seckill(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId){Order order = orderService.createOrder(userId,productId);order.setId(999l);return order;}

yml配置文件添加配置,取消统一上下文

spring:cloud:sentinel:web-context-unify: false      #是否统一web上下文(默认true)

配置链路规则:需要对createOrder限流,则如下设置,设置完之后测试,分别测试create接口和seckill接口,则会发现create接口随便刷新无误,seckill接口就有了一秒一个的限制

3,流控效果设置如下

快速失败:(默认)如果没有超阈值,就交给业务处理,如果超过了,多余的请求就会抛出blockHandler异常(比如每秒一个,哪么这一秒其他多的请求会被直接丢弃)

Warm Up:leng'q如果预见超高峰流量即将到达,设置参数参数QPS(每秒通过几个请求),period(冷启动周期),流程比如QPS=10,period=3,请求是一个稳步上升的趋势,而不是突然增加(每秒多余的请求会被丢弃)

排队等待:匀速排队,比如QPS=2,则每秒会通过2个请求,但其他请求不会被丢弃,而是在后面排队,等前面的请求,排队也有最大等待时间,timeout=100,超过最大等待时间也会被丢弃,如下每秒2个请求

熔断降级(DegradeRule)

思想:如下图的复杂调用关系,A->G->D,B->F->D,如果此时D不稳定,一直不返回结果,那么如果G一直去等D的结果,D也会卡住,同样A也会卡住,此时我们就需要及时切断这种不稳定的调用,当G感知到D调用很慢之后,后面就采取措施不调用或者快速返回,切断跟D的联系,快速返回错误,整个链路才会快速结束,请求不积压,则不会产生服务雪崩问题

此中间就有一个断路器的概念,当调用的B是稳定通畅的,则断路器是关闭的,一旦B出现了问题,则A就会打开,怎么知道什么时候该打开呢,此时就会有一个半开状态,就是稍微开一下,测一下当前状态如果调用不慢了,则闭合,如果调用仍然慢,则打开

断路器工作原理如下:

首先默认断路器是关闭的,调用是通的,此时我们设置慢调用比例(熔断策略:满调用比例/异常比例/异常数),比如设置0.7,就是请求70%都是慢请求(慢调用设置时长阈值)的话,就打开断路器,调用就会失败,但也不能一直打开,此时就会有一个熔断时长,比如30s,这30s以内的所有请求不调用,直接返回失败,但30s之后熔断窗口就结束,结束后断路器就会变成半开状态,A需要调用B就会放一个请求过去探测一下,调用成功,则B又可靠了,断路器闭合,如果还是调用失败或者慢,则断路器还是打开

熔断策略测试案例

慢调用比例

首先运行Order和Product服务,然后给CreateOrder设置熔断规则如下

修改一下商品服务,加个睡眠时长2秒,达到慢请求要求

在productController中的方法里加入睡眠时长

 @GetMapping("/getProductById/{productId}")public Product getProductById(@PathVariable("productId") Long productId, HttpServletRequest request) {String header = request.getHeader("X-Token");System.out.println("product==="+header);try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}Product product = productService.getProductById(productId);return product;}
}

然后测试,调用createOrder接口, 先5秒内刷新超过5个请求吧,开始的请求会比较慢,5秒后就会很快,应为断路器打开了,就不再调用了,后台也不再打印,order服务就会返回兜底回调,30秒之后,在测试刷新接口,会有一个慢请求之后,又会变快,因为半开测试之后,断路器仍旧打开了,选择不调用。去掉getProductById里面的睡眠,在重启商品服务,熔断规则还在,然后再测试接口调用,则正常调用,因为不存在慢调用问题

异常比例

同上构造异常调用

修改一下商品服务,加一个异常

在productController中的方法里加入异常代码

 @GetMapping("/getProductById/{productId}")public Product getProductById(@PathVariable("productId") Long productId, HttpServletRequest request) {String header = request.getHeader("X-Token");System.out.println("product==="+header);
//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }int a=10/0;Product product = productService.getProductById(productId);return product;}

然后同上测试方法进行测试看效果

当没有加熔断的时候通过后天打印可以看出,每次A调用B 之后,都会返回异常,但是每次还是会调用,加了熔断规则之后,达到规则之后,30s内就不会再调用,就直接执行兜底回调,不用再走一遍失败的路

异常数

测试也同上面一样

系统保护(SystemRule)

来源访问控制(AuthorityRule)

热点参数(ParamFlowRule)

类似流控规则,只是更细话到参数上面的限制

测试案例如下

场景1:每个用户秒杀QPS不得超过1(秒杀下单userId级别)

我们可以先写一个资源,在orderController中

   //添加上sentinel资源注解@GetMapping("/seckill")@SentinelResource(value = "seckill-order",blockHandler = "seckillFallback")public Order seckill(@RequestParam(value = "userId",required = false) Long userId, @RequestParam(value = "productId",required = false) Long productId){Order order = orderService.createOrder(userId,productId);order.setId(999l);return order;}public Order seckillFallback(Long userId, Long productId, BlockException e){Order order = new Order();order.setId(-1l);order.setTotalAmount(BigDecimal.ZERO);order.setAddress("异常信息-----");return order;}

启动订单服务,设置热点参数规则 

有参数userId,快速刷新效果,会限制1秒一个

去掉userId,快速刷新效果,不会限制

场景2:6号是vip用户,需要放行,不限制QPS

场景3:666号商品已经下架,不可访问

此时需要对另外一个参数进行限流,则需要再加一个限流规则

3,基础场景

1,下载sentinel-dashboard控制台

https://github.com/alibaba/Sentinel/releases/tag/1.8.8

Sentinel-Dashboard 是 阿里巴巴 开源的 流量控制组件 Sentinel的 可视化控制台 ,主要用于 微服务架构 的流量治理,支持实时监控、动态配置规则、熔断降级等功能

下载好之后,在文件夹中cmd,开启命令模式

然后输入java -jar sentinel-dashboard-1.8.8.jar启动

启动之后,浏览器输入http://localhost:8080/   即可访问,账密sentinel sentinel

2,添加配置

spring:cloud:sentinel:transport:dashboard: localhost:8080   #dashboard控制台eager: true                   #提前加载(本来是访问了请求才会加载,此时项目启动就会连接加载)

3,启动服务之后,查看控制台

4,在OrderServiceImpl得createOrder方法上添加注解@SentinelResource(value = "createOrder")

   @SentinelResource(value = "createOrder")@Overridepublic Order createOrder(Long userId, Long productId) {
//        Product product = getProductByRemoteWithLoadBalancerByAnnotatin(productId);Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1l);//todo  远程调用order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("爱学习");order.setAddress("北京");//todo  远程调用order.setProductList(Arrays.asList(product));return order;}

5,重新启动订单服务,然后调用create接口,查看控制台 

6,测试规则---流控

7,然后调用createorder接口,一秒一刷则无妨,但一秒超过一次请求就会报错

4,异常处理

如上会默认返回一个流控错误字符串,我们需要返回json数据,返回错误消息和数据则就需要异常处理机制,常见得集中异常和处理方式如下:

1,Web接口

-----实现:AbstractSentinelInterceptor

异常处理,我们自己写个异常处理类,实现BlockExceptionHandler,添加到容器

新增类MyBlockExceptionHandler 

package org.example.order.exception;import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.common.R;
import org.springframework.stereotype.Component;import java.io.PrintWriter;@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {private ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,String resourceName, BlockException e) throws Exception {response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();R error = R.error(500, resourceName + "被Sentinel限制了" + e.getClass());//写出jsonString s = objectMapper.writeValueAsString(error);writer.write(s);writer.flush();writer.close();}
}

新增一个异常已处理对象R

在公共model模块添加对象

package org.example.common;import lombok.Data;@Data
public class R {private Integer code;private String msg;private Object data;public static R ok(){R r = new R();r.setCode(200);return r;}public static R ok(Object data, String msg){R r = new R();r.setCode(200);r.setData(data);r.setMsg(msg);return r;}public static R error(){R r = new R();r.setCode(500);return r;}public static R error(Integer code, String msg){R r = new R();r.setCode(code);r.setMsg(msg);return r;}}

然后重新启动,在dashboard中加入流控规则,调用接口,快速刷新即可看到以下报错

2,@SentinelResource

------实现:SentinelResourceAspect

@SentinelResource一般标注在非controller层,一旦违反规则,如果业务规定有回调数据,那就用blockHandle去指定兜底回调,如果没有指定回调,就让异常抛给全局(springboot全局异常处理器),此注解得处理(SentinelResourceAspect)

回调处理

1,在方法上加上注解

 @SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")

2,添加回调方法

加上回调得方法,方法名通上面得注解里面blockHandler,其他内容需通上方注解方法,public、返回、参数

OrderServiceImpl

    //增加回调createOrderFallback@SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")@Overridepublic Order createOrder(Long userId, Long productId) {
//        Product product = getProductByRemoteWithLoadBalancerByAnnotatin(productId);Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1l);//todo  远程调用order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("爱学习");order.setAddress("北京");//todo  远程调用order.setProductList(Arrays.asList(product));return order;}//同一个类中,加上回调得方法,方法名通上面得注解里面blockHandler,其他内容需通上方注解方法,public、返回、参数public Order createOrderFallback(Long userId, Long productId, BlockException e) {Order order = new Order();order.setId(0l);order.setTotalAmount(BigDecimal.ZERO);order.setUserId(userId);order.setNickName("未知用户");order.setAddress("异常信息:"+e.getClass());return order;}

添加流控规则

测试快速刷新的异常处理结果

3,OpenFeign调用

-----实现:SentinelFeignAutoConfiguration

在openFeign笔记中提到过兜底回调,此处即用

首先编写一个兜底返回org.example.order.feign.fallback.ProductFeignClientFallback 

实现ProductFeignClient 接口

package org.example.order.feign.fallback;
import java.math.BigDecimal;import org.example.order.feign.ProductFeignClient;
import org.example.producet.domain.Product;
import org.springframework.stereotype.Component;@Component
public class ProductFeignClientFallback implements ProductFeignClient {@Overridepublic Product getProductById(Long id) {Product product = new Product();product.setId(id);product.setPrice(new BigDecimal("0"));product.setProducetName("兜底回调的数据");product.setNum(0);return product;}
}

在ProductFeignClient 接口中添加fallback = ProductFeignClientFallback.class,这时,在远程调用成功则不管,如果调用失败,则会调用fallback,返回ProductFeignClientFallback里面编写的默认数据

package org.example.order.feign;import org.example.order.feign.fallback.ProductFeignClientFallback;
import org.example.producet.domain.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;//需要调用的服务的名字
@FeignClient(value = "services-product",fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient {@GetMapping("/getProductById/{id}")Product getProductById(@PathVariable("id") Long id);}

添加流控规则

测试异常回调处理结果

同样,如果此处没有些回调函数,就会抛给springboot全局异常处理

4,Sphu硬编码 

以上三种异常处理的源码都会有的编码

SphU.entry(resourceName);

我们也可自定义比如 

try {Entry hahah = SphU.entry("hahah");order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("爱学习");order.setAddress("北京");} catch (BlockException e) {throw new RuntimeException(e);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/92590.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92590.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/92590.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解构未来金融:深入剖析DeFi与去中心化交易所(DEX)的技术架构

今天,我们来聊一个颠覆传统金融界的热门话题——DeFi(去中心化金融)。大家可能听说过它如何承诺将银行、交易所、保险等金融服务构建在一个开放、无需许可的区块链网络上。而这一切魔法的核心,正是其独特的“技术架构”。 在这篇文…

中国西北典型绿洲区土壤水分特征(2018-2019年)

数据集摘要该数据包含张掖绿洲黑河沿岸湿地、过渡带杨树林土壤水分、温度数据。数据采集时间为2018年至2019年,采集地点为张掖绿洲,数据为日数据。该数据集是按照课题制定的试验方案和中国生态系统研究网络编著的陆地生态系统水土气生观测规范进行数据的…

MySQL高可用部署

目录 一、MHA(一主多从模式) 1.环境准备(所有节点) 2. 部署 MySQL 主从复制(MasterSlave) 3.部署 MHA Manager(管理节点) (1)安装 MHA Manager &#xf…

从 XSS 到 Bot 攻击:常见网络攻击防不胜防?雷池 WAF 用全场景防护为网站筑牢安全墙

1. 网络攻击类型当前常见的网络攻击类型包括:重放攻击(HTTP Request Replay Attack):攻击者截获合法用户的 HTTP 请求并重新发送,以欺骗服务器执行相同操作。危害包括消耗服务器资源、大量抓取数据或绕过认证操作敏感接…

【王树森推荐系统】推荐系统涨指标的方法05:特殊用户人群

为什么要特殊对待特殊人群? 新用户,低活用户的行为很少,个性化推荐不准确。个性化的召回和排序都需要基于用户的历史行为,如果历史行为少,个性化就做不好,尤其是新用户,这就需要策略把个性化做的…

Java 大视界 -- Java 大数据在智能家居能源管理与节能优化中的深度应用(361)

Java 大视界 -- Java 大数据在智能家居能源管理与节能优化中的深度应用(361)引言:正文:一、Java 构建的智能家居能源数据架构1.1 多源能耗数据实时采集1.2 家庭能源画像与异常检测二、Java 驱动的节能策略与智能控制2.1 多场景节能…

从零开始的云计算生活——番外5,使用ELK实现对应用日志的监控

目录 一.环境准备 试验机安装 修改文件配置 二.收集测试机(test)日志 配置pipline文件 配置filebeat配置文件 三.收集测试机nginx日志 下载安装nginx 修改filebeat文件 修改pipline文件 四.收集网络服务模块日志 1.DHCP 下载dhcp 修改配置…

Node.js:函数、路由、全局对象

Node.js函数 在JavaScript中,一个函数可以作为另一个函数的参数,可以先定义一个函数,然后进行传递,也可以在传参的地方直接定义 function sayhello(){console.log("hello"); } function run(hello, value){hello();cons…

2025暑期—06神经网络-常见网络3

VGG16网络64个卷积核做两次卷积,填充后编程224X224X64 pooling 两次卷 pooling 三次卷...分辨率降低一半,通道数增加1倍所有卷积核都是3x3, 所有的pooling 都是2x2残差网络每一层的块都有越层的连接。

使用 FastAPI 构建 Elasticsearch API

作者:来自 Elastic Jeffrey Rengifo 学习如何使用 Pydantic 模式和 FastAPI 后台任务,通过实际示例构建一个 Elasticsearch API。 想获得 Elastic 认证吗?查看下一期 Elasticsearch Engineer 培训的时间! Elasticsearch 拥有丰富…

[2025CVPR-目标检测方向]FSHNet:一种用于3D物体检测的全稀疏混合网络。

1. ​简介​ 论文提出了FSHNet(Fully Sparse Hybrid Network),一种用于3D物体检测的全稀疏混合网络。FSHNet旨在解决现有稀疏3D检测器的两大核心问题:长距离交互能力弱和网络优化困难。稀疏检测器(如VoxelNeXt和SAFDN…

MySql 8.0.42 zip版安装教程和使用

今天要装个MySQL,就按照自己以前的教程来做,不知道是不是版本更新了的原因,又遇到了一点小阻碍,于是再记录一下吧。 下载MySQL 下载链接:MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/…

【lucene】实现knn

在 Lucene 中,可以通过 KnnFloatVectorQuery 和 KnnFloatVectorField 来实现 KNN(k-Nearest Neighbors)搜索。以下是具体介绍:1. 功能原理KnnFloatVectorQuery 是 Lucene 用于执行最近邻搜索的查询类,它可以在一个字段…

RabbitMQ实践学习笔记

RabbitMQ实践 以下是关于RabbitMQ实践的整理,涵盖常见场景和示例代码(基于Markdown格式)。内容按模块分类,避免步骤词汇,直接提供可操作的方法: 基础连接与队列声明 使用Python的pika库建立连接并声明队列: import pikaconnection = pika.BlockingConnection(pika.C…

量子生成对抗网络:量子计算与生成模型的融合革命

引言:当生成对抗网络遇上量子计算在人工智能与量子计算双重浪潮的交汇处,量子生成对抗网络(Quantum Generative Adversarial Networks, QGAN)正成为突破经典算力瓶颈的关键技术。传统生成对抗网络(GAN)在图…

VBA 多个选项,将选中的选项录入当前选中的单元格

1、使用LISTBOX插件&#xff0c;选中后回车录入 维护好数据&#xff0c;并新增一个activeX列表框插件 Private Sub Worksheet_SelectionChange(ByVal Target As Range)If Target.Count > 1 Then Exit SubIf Target.Row > 2 And Target.Row < 10 And Target.Column 2…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页-微博点赞量Top6实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解主页-微博点赞量Top6实现 视频在线地址&…

SAP调用外部API

SAP需求将中文字符转化为对应的拼音具体思路,由于sap中没有将中文字符转化为拼音的函数或方法类,则以http请求访问外部服务器发布的API服务,然后获取其返回值即可1.调用外部网站上提供的api缺点:免费次数有限,后需要充值这里是用www格式的json报文*&----------------------…

(12)机器学习小白入门YOLOv:YOLOv8-cls 模型微调实操

YOLOv8-cls 模型微调实操 (1)机器学习小白入门YOLOv &#xff1a;从概念到实践 (2)机器学习小白入门 YOLOv&#xff1a;从模块优化到工程部署 (3)机器学习小白入门 YOLOv&#xff1a; 解锁图片分类新技能 (4)机器学习小白入门YOLOv &#xff1a;图片标注实操手册 (5)机器学习小…

基于Matlab传统图像处理技术的车辆车型识别与分类方法研究

随着计算机视觉和图像处理技术的发展&#xff0c;车辆检测与识别已经成为智能交通系统中的一个重要研究方向。传统图像处理方法通过对图像进行预处理、特征提取、分类与识别&#xff0c;提供了一种无需复杂深度学习模型的解决方案。本研究基于MATLAB平台&#xff0c;采用传统图…