spring cloud之集成sentinel

写在前面

源码 。
本文一起看下spring cloud的sentinel组件的使用。

1:准备

1.1:理论

对于一个系统来说,最重要的就是高可用,那么如何实现高可用呢?你可能会说,集群部署不就可以了,但事实并非这么简单,假定一个不那么靠谱的开发,写了一个不那么靠谱的sql语句,上线之后,DB资源很快耗尽,那么所有需要查询DB的服务都无法处理请求,进而导致这些服务挂掉,而上游的服务因为无法快速得到响应,也会很快的挂掉,进而整个系统都会无法对外提供服务,这其实就是发生了非常可怕的服务雪崩,这个过程可以简单参考下图:
在这里插入图片描述
假定那个不那么靠谱的开发,是在服务D开发了那个不那么靠谱的sql语句,则上线后的后果就是D导致B和C不可用,B和C的不可用又会导致A的不可用,最终整个系统不可用。所以想要真正的实现高可用,除了多节点的集群部署外,我们还需要预防服务雪崩,而本文要学习的sentinel正是这样的一个组件,我们可以叫做容错组件

基本上,导致服务雪崩发生的原因在2个方面,第一个方面是高并发导致的请求量增大,第二方面就是应用内部的异常和错误(就像那个不那么靠谱的sql)。其实sentinel也正是从这两方面来预防服务雪崩的,对于高并发,sentinel可以从外部来限制并发量,对于应用内部异常和错误,sentinel可以进行降级和熔断。我们也会从这方面来展开sentinel的实战环节。

在java中,万物皆对象,在Linux中,万物皆文件,而在sentinel中,万物皆资源,而这里的资源我们可以认为就是接口地址,而对这些资源作用的过程是通过其内部的一个责任链,可以参考下图:
在这里插入图片描述
比如有用来收集数据的StaticSlot,构建调用链的NodeSelectorSlot(形成一个树状的调用关系图),如果业务有需要,我们也可以增加自定义的额slot到这个调用链上。

1.2:安装sentinel

首先在这里 下载可运行的jar包,接着如下操作:

$ java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.2.jar
INFO: Sentinel log output type is: file
INFO: Sentinel log charset is: utf-8
INFO: Sentinel log base directory is: C:\Users\dell9020\logs\csp\
INFO: Sentinel log name use pid is: false

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.5.RELEASE)
 ...

成功后访问http://localhost:8080/#/login,进入登陆页面:
在这里插入图片描述
账号sentinel/sentinel,成功后进入如下页面:
在这里插入图片描述

2:限流实战

限流,或者叫流量整形,是sentinel从外部预防服务雪崩的重要手段。

2.1:基础配置

这部分我们直接来使用sentiniel对我们项目做流量整形,首先,在custom和template模块引入依赖:

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

然后在custom和template模块的application.yml中配置sentinel信息:

spring:
  jpa:
    ...
  cloud:
    sentinel:
      eager: true 
      transport:
        port: 8719
        dashboard: localhost:8080

接着使用@SentinelResource注解标记要进行流量整形的接口,如下:

  • custom模块
dongshi.daddy.sentinel.controller.CouponCustomerController#requestCoupon
@PostMapping("requestCoupon")
@SentinelResource(value = "requestCoupon")
public Coupon requestCoupon(@Valid @RequestBody RequestCoupon request) {
    ...
}
@PostMapping("findCoupon")
@SentinelResource(value = "customer-findCoupon")
public List<CouponInfo> findCoupon(@Valid @RequestBody SearchCoupon request) {
    return customerService.findCoupon(request);
}
  • template模块
// 读取优惠券
@GetMapping("/getTemplate")
@SentinelResource(value = "getTemplate")
public CouponTemplateInfo getTemplate(@RequestParam("id") Long id){
    log.info("Load template, id={}", id);
    /*try {
        // 休眠二十秒模拟超时
        TimeUnit.SECONDS.sleep(20);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }*/
    return couponTemplateService.loadTemplateInfo(id);
}

// 批量获取
@GetMapping("/getBatch")
// 降级要执行的方法
@SentinelResource(value = "getTemplateInBatch", blockHandler = "getTemplateInBatch_block")
public Map<Long, CouponTemplateInfo> getTemplateInBatch(@RequestParam("ids") Collection<Long> ids) {
    log.info("getTemplateInBatch: {}", JSON.toJSONString(ids));
    return couponTemplateService.getTemplateInfoMap(ids);
}
// 降级要执行的方法
public Map<Long, CouponTemplateInfo> getTemplateInBatch_block(
        Collection<Long> ids, BlockException exception) {
    log.info("接口被限流");
    return Maps.newHashMap();
}

接着我们启动服务,如果一切正常的话,就可以看到custom和template这两个模块注册到sentinel上了:
在这里插入图片描述

2.2:通过流控规则进行限流

sentinel支持通过三种方式来进行流量整形:

直接流控:
    针对特定接口(sentinel称为资源)限流
关联流控:
    当某接口(sentinel称为资源)达到限流条件时对关联的接口(sentinel称为资源)进行限流
链路流控:

2.2.1:直接流控

我们对资源getTemplateInBatch进行流控,在sentinel选择template对应的微服务,点击子菜单流控规则,然后点击右上角在这里插入图片描述 添加流控规则,如下:
在这里插入图片描述

为了测试我们使用jmeter来进行测试,jmeter配置可以从这里 下载,配置如下:
在这里插入图片描述
通过按钮在这里插入图片描述 启动,之后查看template模块日志输出如下:

2024-01-08 15:34:44.411  INFO 26504 --- [io-20006-exec-7] d.d.s.c.CouponTemplateController         : getTemplateInBatch: [2,3]
Hibernate: select coupontemp0_.id as id1_0_, coupontemp0_.available as availabl2_0_, coupontemp0_.type as type3_0_, coupontemp0_.created_time as created_4_0_, coupontemp0_.description as descript5_0_, coupontemp0_.name as name6_0_, coupontemp0_.rule as rule7_0_, coupontemp0_.shop_id as shop_id8_0_ from coupon_template coupontemp0_ where coupontemp0_.id in (? , ?)
2024-01-08 15:34:44.904  INFO 26504 --- [io-20006-exec-5] d.d.s.c.CouponTemplateController         : 接口被限流

可以看到第二次执行了熔断逻辑被限流了。

2.2.2:关联流控

jmeter配置下载 。

我们来设置当getTempalte接口qps超过1时限制getBatch接口,配置如下:
在这里插入图片描述
首先我们使用jmeter模拟qps 2不间断访问getTemplate接口,如下:
在这里插入图片描述
启动后,这样,肯定就会触发限流规则了,这样,我们先来启动jmeter,
在这里插入图片描述
之后访问getBatch接口,如下:

http://localhost:20006/template/getBatch?ids=2,3

在这里插入图片描述
查看后台输出:
在这里插入图片描述
然后我们来停止jmeter,再来请求接口,就会恢复正常了:
在这里插入图片描述

2.2.3:链路流控

jmeter配置下载 。
对于同一个资源访问可以来自于不同的链路,针对特定的链路进行流控,就是链路流控了,如下图,上方链路就是被流控的:
在这里插入图片描述

在这里插入图片描述
这里我们模拟从custom模块访问template模块的getBatch接口,为了测试,需要首先在custom模块中增加如下接口:

// 批量获取
@GetMapping("/getBatchFromCustomer")
public Map<Long, CouponTemplateInfo> getTemplateInBatch(@RequestParam("ids") Collection<Long> ids) {
    log.info("getTemplateInBatch111: {}", JSON.toJSONString(ids));
    return templateService.getTemplateInBatch(ids);
}

因为需要进行限流的资源需要知道当前的调用者是谁,才能知道是否需要触发,所以,首先需要在custom模块添加openfeign的拦截器,在openfeign的请求中添加来源头

@Configuration
public class OpenfeignSentinelInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("SentinelSource", "coupon-customer-serv");
    }
}

接着在tempalte模块中获取这个来源的信息:

@Component
@Slf4j
public class SentinelOriginParser implements RequestOriginParser {

    @Override
    public String parseOrigin(HttpServletRequest request) {
        log.info("request {}, header={}", request.getParameterMap(), request.getHeaderNames());
        return request.getHeader("SentinelSource");
    }
}

接着我们来配置sentinel针对来源coupon-customer-serv进行限流,如下:
在这里插入图片描述
接着开启jmeter,正常的话会看到被限流了:
在这里插入图片描述
为了测试来源不匹配的情况不限流,我们将sentinel的目标资源名称随便改为其他的,如下:
在这里插入图片描述
此时再开启jmeter测试就正常了:
在这里插入图片描述

2.3:三种流控效果

sentinel支持三种流控效果,快速失败,warm up,排队等待,在上述的实战环节我们使用就是快速失败,这也是sentinel默认的流控效果。

  • 快速失败
    直接失败。
  • warm up
    这是一种从低水位逐渐拉高的一种限流方式,比如如下的配置:
    在这里插入图片描述
    上图设置在5秒内拉高到10进行限流,而非开始就是10,开始的限流值需要除以冷却因子,这里冷却因子是3,所以就是10/3=3,也就是当qps到达3时开始限流,然后在5秒内将这个限流值拉高到最大值10,
    在这里插入图片描述

使用的场景,如采用缓存+DB读的场景,如果接口一段时间内都处于很低的水位,导致大量的缓存都失效了,此时突然发生了突发流量(某明星出轨了,某漂亮country被原子弹攻击了),此时缓存还没有完全构建起来,为了避免突发流量全部打到DB,把DB打穿,就可以考虑使用warm up,在一段时间内从低水位逐渐拉到高水位,同时在这段时间内完成缓存的构建工作。

  • 排队等待
    被限流的请求在一个任务队列中排队等待,并按照超时等待时间从队列中删除任务,如下500内还没有处理则移除任务的配置:
    在这里插入图片描述

3:降级、熔断实战

jmeter配置 。
降级、熔断,是sentinel从服务内部预防服务雪崩的重要手段。这部分我们一起来看下如何使用sentinel来实现降级和熔断。为了方便测试我们首先在template模块添加一个新的接口并设置为sentinel的资源:

// 批量获取
@GetMapping("/getBatchV1")
// 降级要执行的方法
@SentinelResource(value = "getTemplateInBatchV1", fallback = "getTemplateInBatch_fallback")
public Map<Long, CouponTemplateInfo> getTemplateInBatchV1(@RequestParam("ids") Collection<Long> ids) {
    log.info("getTemplateInBatch: {}", JSON.toJSONString(ids));
    int i = 1 / 0;
    return couponTemplateService.getTemplateInfoMap(ids);
}

public Map<Long, CouponTemplateInfo> getTemplateInBatch_fallback(Collection<Long> ids) {
    log.info("接口被fallback");
    return Maps.newHashMap();
}

这里注意指定了fallback = "getTemplateInBatch_fallback",则当抛出了RuntimeException时就会进入执行降级逻辑,接着我们就需要在sentinel中配置熔断逻辑了,如下:
在这里插入图片描述
降级熔断的判断过程可以参考下图(注意时示例)
在这里插入图片描述
接着执行jemter,日志输出如下:

2024-01-10 14:01:47.813  INFO 13112 --- [io-20006-exec-2] d.d.s.c.CouponTemplateController         : getTemplateInBatch: [2,3] #
2024-01-10 14:01:47.813  INFO 13112 --- [io-20006-exec-2] d.d.s.c.CouponTemplateController         : 接口被fallback 
2024-01-10 14:01:47.813  INFO 13112 --- [o-20006-exec-10] d.daddy.sentinel.SentinelOriginParser    : request org.apache.catalina.util.ParameterMap@39d7b9e0, header=org.apache.tomcat.util.http.NamesEnumerator@7d50964c
2024-01-10 14:01:47.814  INFO 13112 --- [o-20006-exec-10] d.d.s.c.CouponTemplateController         : 接口被fallback
2024-01-10 14:01:47.815  INFO 13112 --- [io-20006-exec-9] d.daddy.sentinel.SentinelOriginParser    : request org.apache.catalina.util.ParameterMap@39d7b9e0, header=org.apache.tomcat.util.http.NamesEnumerator@1f47105b
2024-01-10 14:01:47.816  INFO 13112 --- [io-20006-exec-9] d.d.s.c.CouponTemplateController         : 接口被fallback
....
2024-01-10 14:01:47.813  INFO 13112 --- [io-20006-exec-2] d.d.s.c.CouponTemplateController         : getTemplateInBatch: [2,3] # 1s后半开启,后又重新进入熔断
2024-01-10 14:01:47.813  INFO 13112 --- [io-20006-exec-2] d.d.s.c.CouponTemplateController         : 接口被fallback 
2024-01-10 14:01:47.813  INFO 13112 --- [o-20006-exec-10] d.daddy.sentinel.SentinelOriginParser    : request org.apache.catalina.util.ParameterMap@39d7b9e0, header=org.apache.tomcat.util.http.NamesEnumerator@7d50964c
2024-01-10 14:01:47.814  INFO 13112 --- [o-20006-exec-10] d.d.s.c.CouponTemplateController         : 接口被fallback
2024-01-10 14:01:47.815  INFO 13112 --- [io-20006-exec-9] d.daddy.sentinel.SentinelOriginParser    : request org.apache.catalina.util.ParameterMap@39d7b9e0, header=org.apache.tomcat.util.http.NamesEnumerator@1f47105b
2024-01-10 14:01:47.816  INFO 13112 --- [io-20006-exec-9] d.d.s.c.CouponTemplateController         : 接口被fallback
...

可以看到降级后,满足条件就会进入熔断。一段时间后会尝试恢复,这个状态叫做半熔断,完整的状态转换参考下图:
在这里插入图片描述

写在后面

参考文章列表

jmeter之简单使用 。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

window11后台服务优化记录

这里:\WINDOWS\xxx\svchost.exe -k netsvcs -p 信号聚合器服务&#xff0c;用于根据时间、网络、地理位置、蓝牙和 CDF 因素评估信号。支持的功能包括设备解锁、动态锁定和动态 MDM 策略 参考&#xff1a; 优化参考v1

数字化发展助力青少年阅读回归“慢节奏”

近日&#xff0c;《2024年学前及中小学生寒假分年级阅读推荐书目》发布&#xff0c;正尝试引领青少年阅读在短视频时代回归“慢节奏”。该推荐书目针对每个学龄孩子的学习特点、认知特点、心理特点进行推荐&#xff0c;旨在培养孩子的深度思考能力。 在数字化时代&#xff0c;…

Docker的介绍及安装基本操作命令

前言 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱…

K8S 存储卷

意义&#xff1a;存储卷----数据卷 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的&#xff0c;delete,k8s用控制器创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会回复到初始状态 一旦回到初始状态&#xff0c;所有的后天编辑的文件…

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测 目录 区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CNN-BiLSTM-KDE多…

显示器新赛道Type-C接口

如果把主机比作大脑&#xff0c;那显示器就是眼睛&#xff0c;没有眼睛&#xff0c;大脑再强大也发挥不出效果&#xff0c;所以显示器作为电脑最重要的输出设备&#xff0c;有着举足轻重的地位&#xff0c;可以说在生活中处处都有显示器的影子。其实显示器的历史也是科技发展史…

谈谈Spring Bean

一、IoC 容器 IoC 容器是 Spring 的核心&#xff0c;Spring 通过 IoC 容器来管理对象的实例化和初始化&#xff08;这些对象就是 Spring Bean&#xff09;&#xff0c;以及对象从创建到销毁的整个生命周期。也就是管理对象和依赖&#xff0c;以及依赖的注入等等。 Spring 提供…

GPT 商店强势来袭,人人都要有自己的 GPTs

作者&#xff1a;苍何&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;CSDN 2023 年 实力新星&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#xf…

AlexNet论文翻译与精读

1:该论文解决了什么问题&#xff1f; 图像分类问题 2&#xff1a;该论文的创新点&#xff1f; 1:使用了大的深的卷积神经网络进行图像分类&#xff1b; 2:采用了两块GPU进行分布式训练&#xff1b; 3:采用了Relu进行训练加速&#xff1b; 4:采用局部归一化提高模型泛化能…

DB2除法的小数位问题(四舍五入问题)以及其他常用的函数

DB2除法的小数位问题&#xff08;四舍五入问题&#xff09;以及其他常用的函数 1. DB2取第一条数据2. DB2 中指定值排序2.1 使用case when2.2 使用decode函数 3. 拼接函数4. 强制转换类型——cast函数5. DB2除法的小数位问题&#xff08;四舍五入问题&#xff09;5.1 关于round…

03.C++内存管理笔记

1、C/C内存分布 ①内存分那么多区的原因&#xff1a;不同的数据&#xff0c;有不同的存储需求&#xff0c;各区域满足了不同的需求。 ②存放&#xff1a; 临时变量等临时用的变量&#xff1a;栈区&#xff1b; 动态申请的变量&#xff1a;堆区&#xff1b; 全局变量和静态变…

计算机图形学作业:四阶Bezier曲线、三阶 B 样条曲线

3. 请给出四阶Bezier曲线的矩阵表示形式,并作图绘制出一段四阶Bezier 曲线,要求给出控制点的坐标。(共 20 分) 四阶Bezier曲线的矩阵表示形式为: P(t)=P0P1P2P3P41-46-4104-1212-4006-1260004-4000011ttt3t4 给出控制点为: P0(578,389),P1(1018,175),P2(1442,373),P3(1…

【JaveWeb教程】(20) MySQL数据库开发之 基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询 详细代码示例讲解

目录 1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 在上次学习的内容中&#xff0c;我们讲解了&#xff1a; 使用DDL语句来操作数据库以及表结构&#xff08;数据库设计&…

构建labelstudio镜像的时候,报错node:18,如何解决

解决方案&#xff1a; vi Dockerfile # syntaxdocker/dockerfile:1.3 FROM --platformlinux/amd64 node:18.16-bullseye-slim AS frontend-builder18改成 18.16-bullseye-slim

CodeWave智能开发平台--03--目标:应用创建--09供应商详情页面下

摘要 本文是网易数帆CodeWave智能开发平台系列的第13篇&#xff0c;主要介绍了基于CodeWave平台文档的新手入门进行学习&#xff0c;实现一个完整的应用&#xff0c;本文主要完成09供应商详情页面下主营产品展示及权限管理 CodeWave智能开发平台的13次接触 CodeWave参考资源…

UE 引擎工具笔记

2023虚幻技术分享会视频 1.2023年虚幻引擎最新功能和技巧 [UFSH2023]2023年虚幻引擎最新功能和技巧 | Chris Murphy Epic Games_哔哩哔哩_bilibili 推荐细看下.总结了UE5的功能大概 2.调试技巧 [UFSH2023]总有一个你不知道的虚幻引擎调试技巧 | 陈拓 Epic Games_哔哩哔哩_…

2024.1.11 Kafka 消息队列,shell命令,核心原理

目录 一 . 消息队列 二. Kafka 三 . 启动命令 四 . Kafka的Shell 命令 五 . Kafka的核心原理 1. Topic的分区和副本机制 2 . 消息存储机制 和 查询机制 3. Kafka中生产者数据分发策略 六 . Kafka 之所以具有高速的读写性能&#xff0c;主要有以下几个原因 七. 笔记…

8年经验之谈 —— 服务端性能瓶颈定位思路总结!

01、软件性能测试目标 软件性能测试的目的主要有以下三点&#xff1a; 评价系统当前性能&#xff0c;判断系统是否满足预期的性能需求。 寻找软件系统可能存在的性能问题&#xff0c;定位性能瓶颈并解决问题。 判定软件系统的性能表现&#xff0c;预见系统负载压力&#xff…

Asynchronous FIFO and synchronous FIFO-翻译自外网

Synchronous FIFO 先进先出 (FIFO) 是一种非常流行且有用的设计块&#xff0c;用于模块之间的同步和握手机制。 FIFO 的深度&#xff1a; FIFO 中的槽数或行数称为 FIFO 的深度。 FIFO 的宽度&#xff1a;每个槽或行中可以存储的位数称为 FIFO 的宽度。 在同步 FIFO 中&…

特征工程-特征清洗

特征清洗 在进行玩特征理解后&#xff0c;我们大致理解了面对的数据中包含哪些内容。下一阶段&#xff0c;我么需要对数据中的内容进行进一步分析处理&#xff0c;针对不同数据进行清洗。数据清洗是对数据进行重新审查和校验的过程&#xff0c;目的在于删除重复信息、纠正存在…