抽丝剥茧,Redis使用事件总线EventBus或AOP优化健康检测

news2024/11/15 8:23:50

目录

前言

Lettuce

什么是事件总线EventBus?

Connected

Connection activated

Disconnected

Connection deactivated

Reconnect failed

使用

一种另类方法—AOP

具体实现


前言

在上一篇深入浅出,SpringBoot整合Quartz实现定时任务与Redis健康检测(二)_往事如烟隔多年的博客-CSDN博客

文章中,通过在SpringBoot中使用Quartz实现了Redis健康状态的检测,虽然一定程度上解决了Redis的连接问题,但仍存在一些问题,比如当Redis在定时检测的间隔时间内断开连接时,此时有用户请求进入时仍然会出现服务不可用的状态,那么有办法能够在Redis断开时通知到SpringBoot程序,进而实现Redis到MySQL的切换呢?本文将在之前的基础上使用Redis的事件总线机制来解决该问题。

Lettuce

在SpringBoot 2.x版本中默认使用的Redis客户端为Lettuce,与早期的Jedis不同,Lettuce底层由Netty构建,异步IO驱动提升效率,支持高并发,且线程安全。由下图可以看出项目中引入了Redis依赖后使用的客户端为Lettuce

什么是事件总线EventBus?

虽然引入了Lettuce,但是面临的问题应该如何作以解决呢?这里就得讲一下Redis的EventBus了,可以通过Lettuce官方文档了解相关信息,

Connection Events · lettuce-io/lettuce-core Wiki · GitHub

由于客户端使用了lettuce6.1.10,因此我们关注内容如下Connection Events · lettuce-io/lettuce-core Wiki · GitHub

不难看出自lettuce提供了一个用于使用连接事件的实例代码,通过订阅事件总线可以监听到当前Redis的连接事件状态,连接事件状态分为如下五种:

Connected

传输协议连接建立,即TCP三次握手完成,Socket通信建立,事件类型ConnectedEvent。

Connection activated

逻辑连接建立,当前处于活动状态并且可以开始分发Redis命令,此时ping命令已经发送并收到回应,可以正常使用Redis命令。事件类型ConnectionActivatedEvent。

Disconnected

连接关闭,传输协议关闭或重置。该事件发生在定期关闭和连接中断时,事件类型Disconnected。

Connection deactivated

连接停用,逻辑连接停用,内部的处理状态被重置,并且isOpen()标志被设置为false,该事件发生在定期关闭和连接中断时,事件类型Connection deactivated。

Reconnect failed

重连失败(自5.3版起),尝试重连失败。包含重连失败和重连计数器。事件类型RecconectFailedEvent。

如上五种类型中需要重点关注的是Connection activated,当该连接事件发生时,将Redis连接标识置为true即可。

使用

根据前文提到的官方文档给出的代码,使用后会发现并未监听到Redis的连接状态。

RedisClient client = RedisClient.create()
EventBus eventBus = client.getresources().eventBus();

eventBus.get().subscribe(e -> System.out.println(event));

...
client.shutdown();

此时进入create()方法内部查看情况,可以看到默认无参的构造函数创建了一个RedisClient对象,其中第一个参数为clientResources对象,第二个参数为一个字符串,即空的URI,想必在这里已经猜到为什么无法监听连接了。

由于并没有传入对应的Redis资源或URI路径,导致无法进行正常的事件监听。

在源码中不难发现有其它同名含参的构造方法, 此处使用第三个含有ClientResource对象的方法,因为可以通过Spring注入该对象,从而省去手工构造的繁琐步骤。

具体代码如下

通过创建事件总线对象,进而订阅Redis的连接事件,当Reids处于非连接状态时会实时修改RedisCheckConfig的连接状态标识。即使在Redis定时检测任务的间隔中也能保证服务的正常运行。

@Component
@Slf4j
public class RedisStatusListener {

    @Autowired
    private ClientResources clientResources;

    public RedisClient redisClient() {

        RedisClient client = RedisClient.create(clientResources);
        EventBus eventBus = client.getResources().eventBus();

        eventBus.get().subscribe(e -> {

            RedisCheckConfig.redisConnected = e instanceof ConnectionActivatedEvent ? true : false;
            log.info("EventBus获取Redis是否连接 "+RedisCheckConfig.redisConnected);
        });
        return client;
    }
}

一种另类方法——AOP

如果并不想使用事件总线的方式来解决,这里再提供一种其它的思路。可以通过AOP的方式来完成判断。

通过对Redis操作类中的所有操作指令进行检测,即当Redis操作命令执行超过1s(可调节)时则认为此时Redis出现了连接异常。

这里由于需要统计执行时间需要用到线程池,通过AOP的环绕通知来实现业务逻辑拦截,即当Redis命令操作超过指定时间则返回数据为其对应存储数据的默认类型。

具体实现

@Component
@Aspect
@Slf4j
public class RedisOperationAspect {

    @Around("execution(* com.o2o.shop.util.RedisOperator.*(..))")
    public Object monitorRedisCommandExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法信息
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        String methodName = method.getName();

        // 执行超时时间,单位ms
        long timeout = 1000;

        ExecutorService executor = new ThreadPoolExecutor(1, 1,
                1000, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(1));

        // 创建Future对象
        Future<Object> future = executor.submit(() -> {
            try {
                return joinPoint.proceed();
            } catch (Throwable throwable) {
                log.error("Redis AOP 执行 "+joinPoint+"异常");
                throw new RuntimeException(throwable);
            }
        });

        // 执行方法并等待结果,设置超时时间
        try {
            return future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            // 超时处理
            log.warn("Redis command execution timed out");
            // 中断方法执行
            future.cancel(true);
            // 返回特定结果
            Class<?> returnType = method.getReturnType();

            if (returnType.isPrimitive()) {
                if (returnType == boolean.class) {
                    return false;
                } else if (returnType == char.class) {
                    return '\0';
                } else if (returnType == byte.class || returnType == short.class ||
                        returnType == int.class || returnType == long.class) {
                    return 0;
                } else if (returnType == float.class || returnType == double.class) {
                    return 0.0f;
                }
            }
            return null;
        } finally {
            // 关闭线程池
            executor.shutdown();
        }
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FastAPI 快速学习之 Flask 框架对比

目录 一、前言二、FastAPI 优势三、Hello World四、HTTP 方法五、URL 变量六、查询字符串七、POST 请求八、文件上传九、表单提交十、Cookies十一、模块化视图十二、数据校验十三、自动化文档Swagger 风格ReDoc 风格 十四、CORS跨域 一、前言 本文主要对 FastAPI 与 Flask 框架…

cola架构:有限状态机(FSM)源码浅析及扩展

目录 0. cola状态机简述 1.cola状态机使用实例 2.cola状态机源码解析 2.1 语义模型接口源码 2.1.1 Condition和Action接口 2.1.2 State 2.1.3 Transition接口 2.1.4 StateMachine接口 2.2 Builder模式 2.2.1 StateMachine Builder模式 2.2.2 ExternalTransitionBuil…

Vue3-使用create-vue创建项目

认识create-vue create-vue是Vue官方新的脚手架工具&#xff0c;底层切换到了vite&#xff08;下一代构建工具&#xff09;&#xff0c;为开发提供极速响应。 使用create-vue创建项目 1.前提环境条件 已安装16.0或更高版本的Node.js node -v 2.创建一个Vue应用 npm init…

经典卷积神经网络 - GoogLeNet

GoogLeNet是google推出的基于Inception模块的深度神经网络模型&#xff0c;在2014年的ImageNet竞赛中夺得了冠军&#xff0c;在随后的两年中一直在改进&#xff0c;形成了Inception V2、Inception V3、Inception V4等版本。 Inception块 4个路径从不同层面抽取信息&#xff0…

轻松掌握这几种文件批量重命名方法

文件批量重命名一直是许多人在日常工作中经常遇到的问题。如何快速、准确地重命名文件&#xff0c;同时保证文件名的有序性和可读性&#xff0c;是一个值得探讨的问题。本文将介绍一种利用固乔文件管家软件批量重命名文件的方法&#xff0c;帮助您轻松解决这一难题。 固乔文件管…

解析外贸开发信的结构?营销邮件书写技巧?

做外贸的开发信结构是怎样的&#xff1f;写外贸邮件的注意事项&#xff1f; 外贸开发信是国际贸易中至关重要的一环&#xff0c;它不仅是与潜在客户建立联系的第一步&#xff0c;也是一种有效的市场推广工具。蜂邮EDM将深入解析外贸开发信的结构&#xff0c;帮助您更好地理解如…

基于springboot+vue实现地方美食分享网站项目【项目源码+论文说明】

基于springbootvue实现地方美食分享网站演示 摘要 首先&#xff0c;论文一开始便是清楚的论述了系统的研究内容。其次&#xff0c;剖析系统需求分析&#xff0c;弄明白“做什么”&#xff0c;分析包括业务分析和业务流程的分析以及用例分析&#xff0c;更进一步明确系统的需求…

VulnHub SICKOS: 1.1

一、信息收集 1.nmap扫描 IP&#xff1a;192.168.103.177 开放端口&#xff1a;22、3128、8080 这里可以看到3128端口是作为代理使用的&#xff0c;所以想访问80端口必须走3128端口代理 2.利用burp挂上游代理 然后直接开代理&#xff0c;访问80端口 3.扫描目录 因为3128端…

使用adobe font style 工具绘制的艺术字,请鉴赏。

Adobe Fireflyhttps://firefly.adobe.com/generate/font-styles

简化通知基础设施:开源的消息通知服务 | 开源专题 No.41

novuhq/novu Stars: 22.9k License: MIT Novu 是一个开源的通知基础设施项目&#xff0c;它提供了统一的 API 来通过多个渠道发送通知&#xff0c;包括应用内、推送、电子邮件、短信和聊天。主要功能有&#xff1a; 为所有消息提供商 (应用内、电子邮件、短信、推送和聊天) 提…

安装EasyX--图形库--从代码到图形

一.软件安装 EasyX 是一款针对 Visual C 的免费绘图库软件&#xff0c;免费哦&#xff01;支持 VC6.0 ~ VC2022 EasyX Graphics Library for C 这是它的网址 进入后点机下载即可 双击安装包 在这一步,注意选择适合你电脑上安装的编译器版本,我的电脑安装的是vs2022,那么我选…

微服务、事件驱动架构和 Kafka

想象一下&#xff0c;有一个巨大的整体应用程序&#xff0c;其中许多复杂的功能紧密地联系在一起。可扩展性是一个很大的挑战&#xff0c;部署过程可能会变得非常繁琐&#xff0c;而且由于内部组件高度耦合&#xff0c;改变功能流程也不是那么容易。 也许很多人都熟悉这个概念…

安科瑞无线测温产品在某风电场项目的超温事故预警及分析-安科瑞 蒋静

摘 要&#xff1a;作为保证系统安全运行的重要设备的高压开关柜装置,其内部导电连接处过热会导致电气设备的损坏,更严重的是可能还会发生火灾等严重事故。因此,电力系统中电器设备安全运行的一个重要课题就是对高压开关柜实施在线监测。本文主要研究的是针对高压开关柜接点的无…

JoySSL证书买二送一买三送二特别活动

数字安全对于网站运营和用户信任至关重要。JoySSL作为一家知名的SSL证书品牌&#xff0c;为了回馈广大用户&#xff0c;推出了买二送一和买三送二的特别活动。 超值优惠&#xff1a;买二送一、买三送二 JoySSL的买二送一和买三送二活动非常有吸引力。在买二送一的活动中&#…

互联网医院|互联网医院建设三级等保不可缺

等级保护全称“网络安全等级保护”&#xff0c;指对国家重要信息、法人和其他组织及公民的专有信息以及公开信息和存储、传输、处理这些信息的信息系统分等级实行安全保护&#xff0c;对信息系统中使用的信息安全产品实行按等级管理&#xff0c;对信息系统中发生的信息安全事件…

Spring Cloud Config

Spring Cloud Config 服务端:一个集中化配置中心,可以是一个独立的服务,也可以注册到服务治理中心,它可以集中管理各个 微服务的配置; 作用原理是从某个地方读取(本地/云端)提供给其客户端作为配置; 客户端:作为一个服务端,通过读取Config的服务端来获取自己的配置文件; 服务…

java实现颜色拾色器并打包成exe文件

我们先来看看效果 一.源码 废话不多说&#xff0c;直接上代码&#xff1a; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class ColorPicker extends JFrame {private JButton colorButton;pri…

曼哈顿距离

曼哈顿距离 以7*7为例 在d<n/2时&#xff1a;打印的图案为菱形 例题&#xff1a; 输入奇数n&#xff0c;显示n行星塔。若输入5&#xff0c;则显示 #include<stdio.h> #include<math.h> int main() {int n, i, j, x, y;scanf("%d", &n);x y n …

『C语言进阶』动态内存管理

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f516;系列专栏&#xff1a; C语言、Linux、Cpolar ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 前言一、动态内存函数的介绍1.1 malloc和free函数1.2 calloc函数1.3 realloc函数 二、常见的动态内存错误2.1 …

记一次vue3实现TRSP大华相机拉流的经历

一、背景 业务场景&#xff0c;大华IP相机安装在A城市某建筑场所&#xff0c;工控机是内网通过4G流量卡上网&#xff0c;工控机通过相机采集数据后做故障识别并上传故障信息到地面服务器&#xff0c;地面服务器在B城市。 现需要在地面服务器提供的WEB界面上实现IP相机实时拉流…