[Java]微服务之服务保护
雪崩问题
微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩
雪崩问题产生的原因是什么?
- 微服务相互调用,服务提供者出现故障或阻塞。
- 服务调用者没有做好异常处理,导致自身故障。
- 调用链中的所有服务级联失败,导致整个集群故障
解决问题的思路有哪些?
- 尽量避免服务出现故障或阻塞
- 保证代码的健壮性
- 保证网络畅通
- 能应对较高的并发请求
- 服务调用者做好远程调用异常的后备方案,避免故障扩散
请求限流: 也叫流量整形, 限制访问微服务的请求的并发量,避免服务因流量激增出现故障。
线程隔离: 也叫做舱壁模式,模拟船舱隔板的防水原理。通过限定每个业务能使用的线程数量而将故障业务隔离,避免故障扩散。
服务熔断:由断路器统计请求的异常比例或慢调用比例,如果超出阈值则会熔断该业务,则拦截该接口的请求。
- 熔断期间,所有请求快速失败,全都走fallback逻辑。
- fallback逻辑的作用就是兜底, 让业务失败时不抛出异常, 而是返回默认数据或友好的提示
服务保护技术
Sentinel
入门
Sentinel是阿里巴巴开源的一款微服务流量控制组件。
- 官网地址: https://sentinelquard.io/zh-cn/index.html
- Sentinel 的使用可以分为两个部分:
- 核心库(Jar包):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。在项目中引入依赖即可实现服务限流、隔离、熔断等功能。
- 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。
搭建Sentinel的控制台
- 下载jar包
- 下载地址: Releases · alibaba/Sentinel · GitHub
- 也可以直接使用课前资料提供的jar包
- 运行
- 将jar包放在任意非中文、不包含特殊字符的目录下,重命名为
sentinel-dashboard.jar
- 打开cmd窗口, 然后运行如下命令启动控制台:
// java -jar sentinel-dashboard.jar 启动jar包
// -Dserver.port=8090 配置启动端口, 默认8080端口冲突
// -Dcsp.sentinel.dashboard.server=localhost:8090 控制台服务地址也要改
// -Dproject.name=sentinel-dashboard 配置项目名称
// 以上是启动命令的解释
java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
- 更多配置项: 启动配置项 · alibaba/Sentinel Wiki · GitHub
- 访问服务页面: http://localhost:8090,就可以看到sentinel的控制台了
- 需要输入账号和密码,默认都是:sentinel
- 登录后,即可看到控制台,默认会监控sentinel-dashboard服务本身:
微服务整合
- 目标: 在
cart-service
模块中整合sentinel,连接sentinel-dashboard
控制台 - 引入sentinel依赖
<!--sentinel-->
<dependency><groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 配置控制台:
spring:cloud:sentinel:transport:dashboard: localhost:8090 # sentinel控制台地址
- 访问
cart-service
的任意端点
- 重启
cart-service
,然后访问查询购物车接口, - sentinel的客户端就会将服务访问的信息提交到
sentinel-dashboard
控制台。 - 并展示出统计信息:
- 点击簇点链路菜单,会看到下面的页面:
- 簇点链路,就是单机调用链路。是一次请求进入服务后经过的每一个被Sentinel监控的资源链。
- 默认Sentinel会监控SpringMVC的每一个Endpoint(http接口)。
- 限流、熔断等都是针对簇点链路中的资源设置的。
- 而资源名默认就是接口的请求路径
- 我们的SpringMVC接口是Restful风格,因此购物车的查询、删除、修改等接口全部都是
/carts
路径
- 默认情况下Sentinel会把路径作为簇点资源的名称,无法区分路径相同但请求方式不同的接口,查询、删除、修改等都被识别为一个簇点资源,这显然是不合适的。
- 所以要修改配置,把
请求方式 + 请求路径
作为簇点资源名 cart-service
的application.yml
中添加下面的配置:
spring:cloud:sentinel:transport:dashboard: localhost:8090http-method-specify: true # 开启请求方式前缀
- 重启服务,通过页面访问购物车的相关接口,可以看到sentinel控制台的簇点链路发生了变化:
请求限流
在簇点链路后面点击流控按钮,即可对其做限流配置:
- QPS: 每秒请求次数
- 单机阈值: 触发流量控制的数值
我们利用Jemeter做限流测试,每秒发出10个请求:
- 按照资料中Jmeter稳定, 安装并熟悉工具
- 把资料中的测试文本拖入Jemeter
- 启动测试
- 查看监控结果
可以看出GET:/carts
这个接口的通过QPS稳定在6附近,而拒绝的QPS在4附近,符合我们的预期
线程隔离
限流可以降低服务器压力,尽量减少因并发流量引起的服务故障的概率,但并不能完全避免服务故障。
一旦某个服务出现故障,我们必须隔离对这个服务的调用,避免发生雪崩。
- 比如,查询购物车的时候需要查询商品,
- 为了避免因商品服务出现故障导致购物车其他服务受到影响,
- 我们可以把购物车业务中查询商品的业务隔离起来,限制可用的线程资源
- 这样,即便商品服务出现故障,最多导致查询购物车业务故障,
- 并且可用的线程资源也被限定在一定范围,不会导致整个购物车服务崩溃。
- 所以,我们要对查询商品的FeignClient接口做线程隔离。
设置线程隔离
- 5个并发线程, 如果单线程QPS为2, 则5线程QPS为10
- 也就是说这个查询功能最多使用5个线程, 如果查询商品的接口每秒处理2个请求,则5个线程的实际QPS在10左右,而超出的请求自然会被拒绝。
模拟商品查询慢服务, 配置购物车服务的tomcat的资源上限
@Api(tags = "商品管理相关接口")
@RestController
@RequestMapping("/items")
@RequiredArgsConstructor
public class ItemController {@ApiOperation("根据id批量查询商品")@GetMappingpublic List<ItemDTO> queryItemByIds(@RequestParam("ids") List<Long> ids){// 模拟业务延迟// 休眠500毫秒ThreadUtil.sleep(500);return itemService.queryItemByIds(ids);}}
server:port: 8082tomcat:threads:max: 25 # 最大线程数accept-count: 25 # 队列最大长度(线程满了在队列中等待)max-connections: 100 # 允许的最大连接数
- 查询购物车的接口处理速度比较慢, 其他增删改的接口速度是正常的
我们利用Jemeter,每秒发送100个请求, 让查询购物车接口的线程耗尽, 查看其他接口是否受影响
- 因为查询购物车业务的线程被耗尽, 导致查询购物车失败
- 但是因为做了线程隔离, 添加购物车等业务并没有被影响
- 如果不做线程隔离, 因为商品服务出现问题, 导致查询购物车接口处理非常慢
- 请求一直增加, 业务处理不完, 资源就无法释放,
- 最终导致tomcat资源被耗尽, 整个购物车所有的业务都无法访问了,
- 所以线程隔离的作用就是把可能的故障, 限制在一定范围内, 避免雪崩现象
Fallback
通过线程隔离, 可以对服务起到保护作用, 某一个业务出现问题不会影响其他业务, 但是被隔离的这个业务, 一旦出现问题, 还是会出现业务不可用的问题, 影响用户体验, 所以需要通过后备方案, 处理可能出问题的业务
针对远程调用进行线程隔离, 并设置Fallback
- 将FeignClient作为Sentinel的簇点资源(开启远程监控):
feign:okhttp:enabled: true # 开启OKHttp连接池支持sentinel:enabled: true # 开启sentinel
- FeignClient的Fallback有两种配置方式:
- 方式一: FallbackClass,无法对远程调用的异常做处理
- 方式二: FallbackFactory,可以对远程调用的异常做处理,通常都会选择这种 (推荐)
- 自定义类,实现FallbackFactory,编写对某个FeignClient的fallback逻辑
@Slf4j
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {public ItemClient create(Throwable cause) {return new ItemClient() {@Overridepublic List<ItemDTO> queryItemByIds(Collection<Long> ids) {log.error("查询商品失败", cause);return CollUtils.emptyList();}@Overridepublic void deductStock(List<OrderDetailDTO> items) {log.error("扣减商品库存失败", cause);throw new RuntimeException(cause);}};}
}
- 可以记录一些错误日志, 设置调用失败返回的默认数据, 或者直接抛出异常, 由调用者进行处理
- 将刚刚定义的FallbackFactory注册为一个Bean
public class DefaultFeignConfig {@Beanpublic ItemClientFallbackFactory itemClientFallbackFactory(){return new ItemClientFallbackFactory();}
}
- 在接口中使用自定义FallbackFactory
@FeignClient(value = "item-service",configuration = DefaultFeignConfig.class, fallbackFactory = ItemClientFallbackFactory.class) // 指定拉取的服务名称
public interface ItemClient {@GetMapping("/items") // 指定请求方法和路径List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids); // 指定请求参数和返回值类型@PutMapping("/items/stock/deduct")void deductStock(@RequestBody List<OrderDetailDTO> items);
}
- cart-sevice服务调用hm-api中的ItemClient方法,
- 如果远程调用失败或者失败, 就会执行Fallback逻辑
- 当服务出现问题时, 最大程度的保证用户体验
- 给远程调用接口设置线程隔离
- 使用Jemeter工具耗尽查询购物车的资源, 继续使用购物车服务
- 查询购物车时, 调用商品查询服务失败, 因为商品查询服务资源耗尽
- Fallback逻辑生效, 商品业务给购物车业务返回了默认数据, 而不是抛出异常, 用户体验更稳定
服务熔断
熔断是解决雪崩问题的重要手段。思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求; 而当服务恢复时,断路器会放行访问该服务的请求。
- 作用: 服务熔断的作用就是进一步降低故障服务对网络资源的占用
- 表现: 既然服务已经出现了问题, 就不要再重复请求了, 既占用资源, 又拖慢业务响应
- 前提: 使用服务熔断的前提是配置好Fallback, 保证熔断了进入应急处理, 而不是频繁报错
点击控制台中簇点资源后的熔断按钮,即可配置熔断策略
- 资源名: 给哪个接口设置熔断规则
- 最大RT: 超过200ms被视为慢调用
- 比例阈值: 超过一半触发熔断
- 熔断时间: 熔断后20s内不再请求服务, 而是触发后备逻辑
测试一下:
- 使用Jmeter工具持续发请求, 耗尽查询商品接口的资源, 商品服务出现故障,
- 购物车服务请求商品服务时, 响应速度还是很快,
- 因为慢服务触发熔断, 直接进入后备逻辑, 而不是一直请求商品服务, 浪费网络资源
相关文章:
[Java]微服务之服务保护
雪崩问题 微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩 雪崩问题产生的原因是什么? 微服务相互调用,服务提供者出现故障或阻塞。服务调用者没有做好异常处理,导致自身故障。调用链中的所有服…...
自动驾驶目标检测融合全貌
1、early fusion 早期融合,特点用到几何空间转换3d到2d或者2d到3d的转换,用像素找点云或者用点云找像素。 2、deep fusion 深度融合,也是特征级别融合,也叫多模态融合,如bevfusion范式 3、late fusion 晚融合&#x…...
消息框(Message Box)的测试方法和测试用例
我来帮你了解消息框(Message Box)的测试方法和测试用例的编写。 我已经创建了一个测试用例示例,让我为你解释消息框测试的主要方面: 测试维度: 功能性测试:验证消息框的基本功能是否正常样式测试:确认不同类型消息框…...
Ubuntu 包管理
APT&dpkg 查看已安装包 查看所有已经安装的包 dpkg -l 查找包 apt search <package_name>搜索软件包列表,找到与搜索关键字匹配的包 dpkg与grep结合查找特定的包 dpkg -s <package>:查看某个安装包的详细信息 安装包 apt安装命令 更新…...
[Ubuntu] linux之Ubuntu18.04的下载及在虚拟机中详细安装过程(附有下载链接)
前言 ubuntu 链接:https://pan.quark.cn/s/283509d0d36e 提取码:dfT1 链接失效(可能被官方和谐)可评论或私信我重发 下载压缩包后解压 !!安装路径不要有中文 下载后解压得到.iso文件,不要放在…...
ffmpeg安装(windows)
ffmpeg安装-windows 前言ffmpeg安装路径安装说明 前言 ffmpeg的安装也是开箱即用的,并没有小码哥说的那么难 ffmpeg安装路径 这就下载好了! 安装说明 将上面的bin目录加入到环境变量,然后在cmd中测试一下: C:\Users\12114\Desktop\test\TaskmgrPlayer\x64\Debug>ffmpe…...
服务器数据恢复—raid6阵列硬盘被误重组为raid5阵列的数据恢复案例
服务器存储数据恢复环境: 存储中有一组由12块硬盘组建的RAID6阵列,上层linux操作系统EXT3文件系统,该存储划分3个LUN。 服务器存储故障&分析: 存储中RAID6阵列不可用。为了抢救数据,运维人员使用原始RAID中的部分…...
linux内核编译启动总结
linux kernel 编译 升级汇总 写在前面内核编译获取kernel代码开始前的准备工作 编译过程1\.解压与净化将下载好的linux内核解压至/usr/src 2\. 得到源代码后,将其净化3\. 配置要进行编译的内核4.编译内核. (15分钟)5.编译模块.方法1:方法2: 6…...
Android Studio的AI工具插件使用介绍
Android Studio的AI工具插件使用介绍 一、前言 Android Studio 的 AI 工具插件具有诸多重要作用,以下是一些常见的方面: 代码生成与自动补全 代码优化与重构 代码解读 学习与知识获取 智能搜索与资源推荐实际使用中可以添加注释,解读某段代…...
本地部署 WireGuard 无需公网 IP 实现异地组网
WireGuard 是一个高性能、极简且易于配置的开源虚拟组网协议。使用路由侠内网穿透使其相互通讯。 第一步,服务端(假设为公司电脑)和客户端(假设为公司外的电脑)安装部署 WireGuard 1,点此下载(…...
asyncio.ensure_future 与 asyncio.create_task:Python异步编程中的选择
asyncio.ensure_future 与 asyncio.create_task:Python异步编程中的选择 引言asyncio.ensure_futureasyncio.create_task两者的区别参数接受范围任务调度的保证代码可读性 哪个更好?使用asyncio.create_task使用asyncio.ensure_future 结论参考 引言 在…...
CTF之密码学(密码特征分析)
一.MD5,sha1,HMAC,NTLM 1.MD5:MD5一般由32/16位的数字(0-9)和字母(a-f)组成的字符串 2.sha1:这种加密的密文特征跟MD5差不多,只不过位数是40(sha256:64位;sha512:128位) 3.HMAC:这…...
JVM调优篇之JVM基础入门AND字节码文件解读
目录 Java程序编译class文件内容常量池附录-访问标识表附录-常量池类型列表 Java程序编译 Java文件通过编译成class文件后,通过JVM虚拟机解释字节码文件转为操作系统执行的二进制码运行。 规范 Java虚拟机有自己的一套规范,遵循这套规范,任…...
EXCEL截取某一列从第一个字符开始到特定字符结束的字符串到新的一列
使用EXCEL中的公式进行特定截取 假设列A是一组产品的编码,我们需要的数据是“-”之前的字段。 我们需要在B1单元格输入公式“LEFT(A1,SEARCH("-",A1)-1)”然后选中B1至B4单元格,按“CTRLD”向下填充,就可以得出其它几行“-”之前的…...
数据库期末复习题库
1. Mysql日志功能有哪些? 记录日常操作和错误信息,以便了解Mysql数据库的运行情况,日常操作,错误信息和进行相关的优化。 2. 数据库有哪些备份方法 完全备份:全部都备份一遍表备份:只提取数据库中的数据࿰…...
私有库gitea安装
一 gitea是什么 Gitea是一款自助Git服务,简单来说,就是可以一个私有的github。 搭建很容易。 Gitea依赖于Git。 类似Gitea的还有GitHub、Gitee、GitLab等。 以下是安装步骤。 二 安装sqilite 参考: 在windows上安装sqlite 三 安装git…...
关于最近win11不能使用ie,而不能使用考试客户端的解决方法
弄ie的那个我感觉是非常难的,所以我的是另一种的方法 下载360浏览器(不是360全家桶)360安全浏览器-全面保护上网安全,4亿用户共同选择(上面的是官网,不要下载错了,还有安装界面注意不要勾选一下…...
深度学习之Mask-R-CNN
1.1 Mask-RCNN 的网络结构示意图 其中黑色部分为原来的Faster-RCNN,红色部分为在Faster网络上的修改: 1)将ROI Pooling层替换成了ROIAlign; 2)添加并列的FCN层(Mask层); …...
css包含块
包含块 出现 在css中一些属性的计算可能超出你的预料,在普遍情况下会认为定位属性和百分比的宽高是根据父元素计算的,但是准确来说他们都是根据元素所在的包含块来计算的,所以掌握包含块的知识是非常关键的。 内容 在CSS中,“…...
混沌工程/混沌测试/云原生测试/云平台测试
背景 私有云/公有云/混合云等具有复杂,分布式,环境多样性等特点,许多特殊场景引发的线上问题很难被有效发现。所以需要引入混沌工程,建立对系统抵御生产环境中失控条件的能力以及信心,提高系统面对未知风险得能力。 …...
研发设计数字化:PLM、PDM、ERP介绍及其区别
一、产品全生命周期管理的定义 1.1 产品全生命周期(PLM)发展背景 目前,数字化设计与制造的技术(如CAX、DFX等)已经在产品开发中得到广泛应用,而各种企业和产品管理软件(如ERP、SCM、PDM、CRM等…...
Python练习51
Python日常练习 题目: 调用函数fun判断一个三位数是否“水仙花数”。 在main函数中从键盘输入一个三位数,并输 出判断结果。请编写fun函数。 说明: 所谓“水仙花数”是指一3位数,其各位数字立方和 等于该数本…...
Qt 前置课程 QtNFC
文章目录 详解 Qt NFC 模块(QtNFC)1. 什么是 NFC?2. NFC 的原理2.1 主动设备与被动设备2.2 三种工作模式2.3 数据交换 3. QtNFC 模块概述4. 使用 QtNFC 模块4.1 配置 .pro 文件 5. NFC 的常见应用场景6. QtNFC 模块的主要类6.1 QNearFieldMan…...
【论文阅读】 Learning to Upsample by Learning to Sample
论文结构目录 一、之前的上采样器二、DySample概述三、不同上采样器比较四、整体架构五、设计过程(1)初步设计(2)第一次修改(3)第二次修改(4)第三次修改 六、DySample四种变体七、复…...
堆排序(含证明)
引言 前面我们讲过堆的基本操作的实现,现在给定一个int类型的数组,里面存放的数据是无序的,我们如何利用堆的思想来实现数组内数据的升序排列或降序排列呢? 通过前面讲到的堆的实现,我们可以想到,我们再开…...
蓝桥杯模拟题不知名题目
题目:p是一个质数,但p是n的约数。将p称为是n的质因数。求2024最大质因数。 #include<iostream> #include<algorithm> using namespace std; bool fun(int x) {for(int i 2 ; i * i < x ; i){if(x % i 0)return false;}return true; } int main() …...
C#中的工厂模式
在C#中,工厂模式(Factory Pattern) 是一种常见的设计模式,它属于创建型模式,主要用于定义一个用于创建对象的接口,让子类决定实例化哪一个类。通过使用工厂模式,客户端代码不需要直接实例化具体…...
深度学习与持续学习:人工智能的未来与研究方向
文章目录 1. 持续学习与深度学习1.1 深度学习的局限1.2 持续学习的定义 2. 目标与心智2.1 奖励假说2.2 心智的构成 3. 对研究方法的建议3.1 日常写作记录3.2 中立对待流行趋势 1. 持续学习与深度学习 1.1 深度学习的局限 深度学习注重“瞬时学习”,如ChatGPT虽在语…...
OGRE 3D----4. OGRE和QML共享opengl上下文
在现代图形应用开发中,OGRE(Object-Oriented Graphics Rendering Engine)和QML(Qt Modeling Language)都是非常流行的工具。OGRE提供了强大的3D渲染能力,而QML则用于构建灵活的用户界面。在某些应用场景中,我们需要在同一个应用程序中同时使用OGRE和QML,并且共享OpenGL…...
【Umi】常用配置
具体见:alias 1. 基础配置 1)配置别名alias 2)配置sourcemap devtool 配置项 3)添加hash 4)图片转base64 inlineLimit 配置项 5)设置JS压缩方式 jsMinifier (webpack) 、jsMinifierOptions 配置项 6)设置umi插件 plugins 配置项 7)设置打包后资源导入的路…...
室内设计效果图欧式风格/seo免费自学的网站
输出重定向 > 重定向正确输出2> 重定向错误输出&> 重定向全部 重定向正确输入到file 重定向错误输入到file.err 重定向全部输入到file.all 重定向会覆盖掉原来的内容可以使用输出追加:把>改成>> 管道的应用 "|"管道的作用是将一条命令的…...
网站建设大作业选题/开发外包网站
这几天在学校呆着,大家遇到了一些网络问题。在这里集中写一下。 客户端打不开 学校的客户端打不开,症状是双击之后,没有反应。这种问题有两种方法:1.重启电脑。一般这方法可以奏效,万能的重启。2.卸掉客户端࿰…...
html网站两边的浮窗怎么做/如何快速推广app
今天在用批处理进行mysql自动备份的过程中遇到一个问题,错误提示:mysqldump: Got error: 2003: Cant connect to MySQL server on 127.0.0.1 (10061) 批处理命令: echo off echo ------------------------- echo mysql backup echo ----…...
黄石建设工程信息网/暴风seo论坛
1. 无地形的贴地 2. 有地形的贴地 1. 无地形的“贴地” Cesium在创建Viewer视景器对象时,当我们将terrainProvier属性指定为EllipsoidTerrainProviderd对象时,那么就对应无地形的三维场景这种情况了, const viewer = new Cesium(targetID,{...,terrainProvider: new Cesiu…...
wordpress音乐盒/东莞seo网站排名优化公司
1. 流水线实现多周期指令简图2. MIPS流水线基本流程1. 取指令;2. 读寄存器和译码;3. 执行ALU和地址计算;4. 存储器访问;5. 写结果到寄存器。3. 非流水与流水的对比:非流水的执行时间– 3条指令共需3800=240…...
国企门户网站建设情况汇报/网络推广官网首页
1 打开游标(V$open_cursor),这一步主要工作是pga中为sql准备内存。 2 解析。(根据sql文本的hash值,找到对应bucket,搜索bucket后的链表,查找对应的父游标句柄,然后在父游标堆0中查找子游标句柄,如果找的到…...