Redis实现简易哨兵模式

故事背景

在一个月黑风高的夜晚,突然收到公司微信群的一条消息,一台生产服务器挂了,里面有部署到redis,让我们查查看服务有没有用到这个redis。经调查发现一个旧的支付服务有用到,接着我们快马加鞭登上服务器看看有没有报错信息,结果发现一切正常,才松了一口气。

后面发现redis挂了之后也没影响业务的原因是因为旧的框架使用了简易哨兵模式:开启一个线程检测redis心跳,如果连接不上就把状态设为不可用,调用redis方法就会直接返回,这样就不会报错或者卡住业务,如果redis连接正常则正常使用。

简易哨兵实现

1.初始化读取配置文件,加载redis配置,里面有一个activeServers和downServers分别代表可用和失效的缓存服务器

checkActive的实现

2.在获取jedis实例的时候会扫描activeServers

3.有一个心跳定时任务会定期检测activeServers是否可用,代码设置了10秒检测一次。

代码重构

由于这是很旧的框架,修改起来很困难,后面打算弃用了,用网上封装的redisCache去实现redis操作,但是网上封装的没有做到这种检测心跳的模式,如果redis服务器挂了,就意味着服务会尝试连接,然后抛出异常变得不可用。由于我们系统的并发不算太高,去掉redis也不会出现缓存穿透打爆数据库的情况,所以我把旧框架的简易哨兵模式搬过来使用,保证redis挂掉也不会影响服务使用。

1、redis工具类添加active状态,启用线程定时检查redis心跳。

springbean初始化方法可以通过构造器实现、@PostConstruct注解、InitializingBean接口、@Bean的initMethod属性,我这里选择用@PostConstruct注解实现线程定时检测redis心跳。

2、写一个切面判断redis的active状态,如果不可用则直接返回

注入失败

在redisCache创建active参数设置为true,然后在其他地方读取active参数的时候发现active无法读取

研究了很久,也问了几个大哥,发现应该是代理类的属性没有注入,需要获取原对象才能正确获取属性。 为什么生成代理类呢,那是因为做了aop增强,如果有做切面,就要通过get方法获取属性。测试了一下生成代理对象是因为有aop切面,或者对象方法里面有@Transactional注解。

要怎么才能正确读取代理对象中的active属性呢?调用get方法,就会走代理方法正确获取属性,直接调用代理对象属性就为空。但是因为我在@Around切面获取get方法会进入死循环,所以需要把active属性改成static全局变量,如果类.static获取即可解决。

AOP的原理可以简单这么认为,代理对象持有被代理对象(因为代理对象的字段并不会被赋值,都是null,所以需要用到被代理对象字段的值),通过在调用被代理对象方法前后做一些事情。

为什么不会赋值? 参考www.zhihu.com/question/37...

总结

1、心跳检测在很多地方都会用到,比如nacos注册中心、服务检测、nginx等。可通过定时发送心跳检测服务是否正常运行,如果检测失败则剔除出集群。

2、spring bean注入也是面试和工作中其中一个考点。对于属性依赖注入需要@Autowired注解修饰,调用类需要用@Component等注解修饰,交给spring管理。因为上面的redisCache是经过切面,生成了代理对象,如果想调用属性只能设置static。

相关推荐
iuyou️19 分钟前
Spring Boot知识点详解
java·spring boot·后端
北辰浮光21 分钟前
[Mybatis-plus]
java·开发语言·mybatis
一弓虽31 分钟前
SpringBoot 学习
java·spring boot·后端·学习
南客先生35 分钟前
互联网大厂Java面试:RocketMQ、RabbitMQ与Kafka的深度解析
java·面试·kafka·rabbitmq·rocketmq·消息中间件
ai大佬38 分钟前
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
java·spring·自动化·api中转·apikey
姑苏洛言39 分钟前
扫码小程序实现仓库进销存管理中遇到的问题 setStorageSync 存储大小限制错误解决方案
前端·后端
头顶秃成一缕光1 小时前
Redis的主从模式和哨兵模式
数据库·redis·缓存
光而不耀@lgy1 小时前
C++初登门槛
linux·开发语言·网络·c++·后端
Mr__Miss1 小时前
面试踩过的坑
java·开发语言
观无1 小时前
Redis安装及入门应用
数据库·redis·缓存