当前位置: 首页 > news >正文

Redis生产实战-Redis集群故障探测以及降级方案设计

Redis 集群故障探测

在生产环境中,如果 Redis 集群崩溃了,那么会导致大量的请求打到数据库中,会导致整个系统都崩溃,所以系统需要可以识别缓存故障,限流保护数据库,并且启动接口的降级机制

降级方案设计
我们在系统中操作 Redis 一般都是通过工具类来进行操作的,假设工具类有两个 RedisCacheRedisLock,那么通过 AOP 对这两个工具类的所有方法做一个切面,如果在这两个类中执行 Redis 操作时,Redis 挂掉了,就会抛出异常(Redis 连接失败),那么我们在切面的处理方法上捕捉异常,再记录下来,判断是 Redis 集群挂了还是展示网络波动

判断是集群挂掉还是网络波动的话,我们可以配置规则,比如 30 秒内出现了 3 次 Redis 连接失败,就认为 Redis 挂掉了(可以使用 Hotkey 配置规则),那么如何自动恢复呢?可以设置 hotkey 中的缓存过期时间,设置为 60 秒,那么缓存过期之后,会再次尝试去操作 Redis,如果 Redis 恢复了就可以正常使用了,如果还没有恢复,会继续向 hotkey 中 set 数据,切面中记录 Redis 故障代码如下:

@Around("redisCachePointcut() || redisLockPointcut()")
public Object around(ProceedingJoinPoint point) {// 签名信息Signature signature = point.getSignature();// 强转为方法信息MethodSignature methodSignature = (MethodSignature) signature;// 参数名称String[] parameterNames = methodSignature.getParameterNames();//执行的对象Object target = point.getTarget();log.debug("处理方法:{}.{}", target.getClass().getName() , methodSignature.getMethod().getName());Object[] parameterValues = point.getArgs();//查看入参log.debug("参数名:{},参数值:{}", JSONObject.toJSONString(parameterNames), JSONObject.toJSONString(parameterValues));Class returnType = methodSignature.getReturnType();// 返回类型是否布尔类型boolean booleanType = boolean.class.equals(returnType) || Boolean.class.equals(returnType);try {if (Objects.nonNull(JdHotKeyStore.get("redis_connection_failed"))) {// 值不为空表示redis连接失败,这里就不再继续请求redis了,直接返回false或者nulllog.error("获取缓存失败,redis连接失败,直接返回 false 或者 null");if (booleanType) {return false;}return null;}return point.proceed();} catch (Throwable throwable) {log.error("执行方法:{}失败,异常信息:{}", methodSignature.getMethod().getName(), throwable);/** redis连接失败,不抛异常,返回空值,* 继续用数据库提供服务,避免整个服务异常* 一分钟之内或者30秒之内出现了几次redis连接失败* 此时可以设置一个key,告诉hotkey,redis连接不上了,指定1分钟左右的过期时间* 下次获取缓存的时候,先根据hotkey来判断,redis是否异常了* hotkey在1分钟之后,会删除key,下次再有redis请求过来,重新去看redis能否连接* 这样可以简单的实现redis挂掉之后直接走数据库的降级*/if (JdHotKeyStore.isHotKey("redis_connection_failed")) {JdHotKeyStore.smartSet("redis_connection_failed", "{}");}// 让后续操作继续,判断返回类型是Boolean则返回false,其他类型返回nulllog.error("缓存操作失败,直接返回 false 或者 null");if (booleanType) {return false;}return null;}
}

如果 Redis 故障的话,通过 key=redis_connection_failed 就已经记录下来了,那么降级操作的话,就从本地缓存 caffeine 中取数据,如果取不到,再查询数据库,降级流程如下:

在这里插入图片描述

这里如果本地缓存中没有数据的话,需要查询数据库之后,再将数据库中的数据放入本地缓存中,这里还是需要加锁的,那么我们就加本地锁即可 ReentrantLock

相关文章:

  • 【注册测绘师备考——8.宁夏回族自治区测绘管理条例】
  • 为 Compose MultiPlatform 添加 C/C++ 支持(2):在 jvm 平台使用 jni 实现桌面端与 C/C++ 互操作
  • 持续集成交付CICD:Jenkins流水线实现Nexus制品晋级策略
  • python+pytest接口自动化(12)-自动化用例编写思路 (使用pytest编写一个测试脚本)
  • 2023济南大学acm新生赛题解
  • android-xml语法
  • go-fastfds部署心得
  • 办公word-从不是第一页添加页码
  • this.$emit(‘update:isVisible‘, false)作用
  • 使用脚手架创建项目并为拆分页面各自的组件(Web3项目二实战之一)
  • 半导体划片机助力氧化铝陶瓷片切割:科技与工艺的完美结合
  • 科幻未来HUD人工智能科技数据图表仪表盘UI界面AI矢量设计素材图
  • 记录一次云原生线上服务数据迁移全过程
  • 【electron】外语函数接口 FFI
  • 前端开发tips
  • C# 免费离线人脸识别 2.0 Demo
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • CSS盒模型深入
  • Facebook AccountKit 接入的坑点
  • Java 内存分配及垃圾回收机制初探
  • Java新版本的开发已正式进入轨道,版本号18.3
  • js如何打印object对象
  • k个最大的数及变种小结
  • Puppeteer:浏览器控制器
  • Tornado学习笔记(1)
  • vue2.0项目引入element-ui
  • VuePress 静态网站生成
  • 阿里云购买磁盘后挂载
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 检测对象或数组
  • 警报:线上事故之CountDownLatch的威力
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 数组的操作
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 学习使用ExpressJS 4.0中的新Router
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 大数据全解:定义、价值及挑战
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ‌移动管家手机智能控制汽车系统
  • # centos7下FFmpeg环境部署记录
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #pragma pack(1)
  • (27)4.8 习题课
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (k8s)kubernetes集群基于Containerd部署
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (南京观海微电子)——COF介绍
  • (数据结构)顺序表的定义
  • (转)http-server应用
  • ***通过什么方式***网吧
  • .Net Core 中间件与过滤器
  • .Net MVC4 上传大文件,并保存表单