【可用性】Redis作为注册中心配合Spring Task的高可用案例

需求:

        假设当前有一个短信服务是多节点集群部署,我们希望每个服务节点在启动时能将服务信息"注册"到redis缓存中,所有服务节点每隔3分钟上报一次,表示当前服务可用。每个服务还会作为哨兵节点每隔10分钟查询一次redis,将没有即时上报的服务节点从redis中剔除。

步骤:

        (1)创建一个Springboot工程,由于要使用到Spring Task定时任务,所以在启动类上标注@EnableScheduling注解

@SpringBootApplication
@EnableScheduling//s开启定时功能
public class SmsApplication {
    public static void main(String[] args) {
        SpringApplication.run(SmsApplication.class,args);
    }
}

        (2)定义一个ServerRegister类,实现服务注册、服务上报、服务检查等逻辑

@Component
public class ServerRegister implements CommandLineRunner {
    
    //服务的唯一标识
    public static String SERVER_ID = null;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 项目启动时自动执行该方法
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        //服务注册方法
        registrationService();
    }
}

        代码解读

        1、ServerRegister需要标注@Component注解配置成bean,装载到Spring容器中。

        2、ServerRegister需要实现CommandLineRunner接口,重写run方法,在项目启动时会自动执行run方法中的逻辑,我们可以在run方法中实现服务注册功能。

        (3)服务注册逻辑

private void registrationService(){
        //通过UUID随机生成服务节点的唯一标识
        SERVER_ID = UUID.randomUUID().toString();
        System.out.println("当前服务实例唯一标识:" + SERVER_ID);
        
        //将服务节点信息以Hash结构存储        
redisTemplate.opsForHash().put(RedisConstants.REGISTRY_CENTER,SERVER_ID,System.currentTimeMillis());
    }

        SERVER_ID服务节点唯一标识,通过UUID随机生成一段字符串作为节点的唯一标识。

        Hash结构图解

        (4)服务上报逻辑

/**
     * 定时服务上报
     * 每隔三分钟定时上报
     * 上报的逻辑:修改value为当前时间戳
     */
    @Scheduled(initialDelay = 10000,fixedRate = 180000)
    public void keepAlive(){
        System.out.println("定时上报,上报服务唯一标识:" + SERVER_ID);
        redisTemplate.opsForHash().put(RedisConstants.REGISTRY_CENTER,SERVER_ID,System.currentTimeMillis());
    }

        上报逻辑其实就是修改了一下服务节点对应的value时间戳,如果服务挂了那么服务肯定无法执行该逻辑,以此来判断服务是否仍然可用。

        initialDelay属性表示从项目启动后延迟多久开始执行定时任务。

        fixedRate属性表示每次任务执行的时间间隔。

        两个属性都是以ms为单位。

        (5)服务检查逻辑

/**
     * 定时服务检查
     * 每隔十分钟定时检查
     * 检查逻辑:每隔服务的最后一次上报时间与当前时间的差值 > 5分钟则将服务实例从redis中剔除
     */
    @Scheduled(initialDelay = 10000,fixedRate = 600000)
    public void checkServer(){
        System.out.print("进行服务实例的检查,执行当前任务的服务为:" + SERVER_ID);

        String center_key = RedisConstants.REGISTRY_CENTER,SERVER_ID;
        //获得Redis中注册的所有服务实例id
        Map map = redisTemplate.opsForHash().entries(center_key );

        //获取当前系统时间戳
        long current = System.currentTimeMillis();

        //保存没有及时上报的服务节点唯一标识
        List removeKeys = new ArrayList();
        map.forEach((key,value) -> {//key为服务实例id,value为上报的系统时间戳
            long parseLong = Long.parseLong(value.toString());
            if(current - parseLong > (1000 * 60 * 5)){
                //当前服务实例超过5分钟没有上报
                removeKeys.add(key);
            }
        });

        //清理服务实例
        removeKeys.forEach(key ->{
            System.out.print("清理服务实例:"+key);
            redisTemplate.opsForHash().delete(RedisConstants.REGISTRY_CENTER,key);
        });
    }

       检查逻辑其实就是将一些没有及时修改value(时间戳)的服务节点从hash结构中删除,因为服务如果是正常状态,那么它肯定能及时更新value,没有及时更新说明服务已经不可用了,需要从redis中剔除。

        为什么是5五分钟检查以此而不是3分钟检查一次?

        有时候可能会因为网络问题导致服务节点上报不及时,而不是因为服务节点真的挂了,此时我们不应该将服务节点从redis中剔除,多预留的2分钟就是为了避免这种情况发生。

        (6)RedisConstants常量类

public class RedisConstants {

    public static String REGISTRY_CENTER = "Service_REGISTRY_Collection";
}

测试:

        (1)启动redis-server

        (2)运行启动类的run方法启动项目

        (3)测试结果

        Redis gui工具:

总结:

        1、每个服务在启动时都会通过UUID生成随机字符串作为自己的唯一标识,随后基于Hash结构将每个服务的唯一标识和时间戳存储在redis中。

        2、服务上报(保活)实际上就是不断修改value时间戳,以此来表示服务仍可用。

        3、服务检查会对所有保存在Hash结构中的服务节点进行检查,判断上报时间是否在规定范围内,没有及时上报的服务节点会从Hash结构中剔除。

        4、方案缺陷是每个服务间的系统时钟不能偏差太多,否则会存在误判,将一些正常服务从redis中剔除。

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

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

相关文章

STM32-I2C通讯-AHT20温湿度检测

非常感谢,提供的视频学习 https://www.bilibili.com/video/BV1QN411D7ak/?spm_id_from333.788&vd_source8ca4826038edd44bb618801808a5e076 该文章注意:串口显示中文会乱码,必须选用支持ASCII的串口助手,才能正常显示中文。…

针对这两个趋势,3.0全新新零售商业模式可以采取以下策略:

国内市场确实存在“消费升级”和“消费降级”两个趋势,这是由于不同消费者群体的需求和购买力存在差异。消费升级主要发生在高端市场,消费者愿意为高品质、高价值、高价格的商品和服务付出更多。而消费降级则主要发生在中低端市场,消费者更加…

ROS学习笔记(七)---参数服务器

ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序(简例) 03. ROS学习笔记(三)—好用的终端Terminator 04. ROS学习笔记(四)—使用 VScode 启动launch文件运行多个节点 05. ROS学习笔…

Golang(壹)

爱情不需要华丽的言语,只需要默默的行动。 简介 应用领域: 下载vscode 使用vscode Go下载 - Go语言中文网 - Golang中文社区 下载sdk 解压到文件中,打开sdk解压文件 穿插dos操作系统知识点: 测试go语言环境 看到vscode 的目录结…

Redis学习笔记(二)

1. 说一说Redis集群的应用和优劣势 参考答案 优势: Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的…

智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.闪电连接过程算法4.实验参数设定…

Idea远程debugger调试

当我们服务部署在服务器上,我们想要像在本地一样debug,就可以使用idea自带的Remote JVM Debug 创建Remote JVM Debug服务器启动jar打断点进入断点 当我们服务部署在服务器上,我们想要像在本地一样debug,就可以使用idea自带的 Remote JVM Debug) 创建Rem…

UE5 水材质注意要点

1、两个法线反向交替流动,可以去观感假的现象 2、水面延边的透明度低 3、增加水面延边的浪花 4、增加折射 折射要整体质量至少在High才有效果 改为半透明材质没有法线信息? 5、处理反射效果 勾选为true 找到这个放在水域 勾为false,即可有非…

FPGA 实现 LeNet-5 卷积神经网络 数字识别,提供工程源码和技术支持

目录 1、前言LeNet-5简洁基于Zynq7020 的设计说明PL 端 FPGA 逻辑设计PS 端 SDK 软件设计免责声明 2、相关方案推荐卷积神经网络解决方案FPGA图像处理方案 3、详细设计方案PL端:ov7725摄像头及图像采集PL端:图像预处理PL端:Xilinx推荐的图像缓…

CentOS:Docker 创建及镜像删除

1、安装docker 远程连接服务器,可以直接下载netsarang比较好用 家庭/学校免费 - NetSarang Website 如果有残留docker未删除干净,请使用 sudo yum -y remove docker docker-common docker-selinux docker-engine Step1:安装必要的一些…

scrapy的入门和使用

scrapy的入门使用 学习目标: 掌握 scrapy的安装应用 创建scrapy的项目应用 创建scrapy爬虫应用 运行scrapy爬虫应用 scrapy定位以及提取数据或属性值的方法掌握 response响应对象的常用属性 1 安装scrapy 命令:     sudo apt-get install scrapy 或者&#x…

警惕!5本剔除!中科院1区TOP,IF8.8,预警高风险期刊更名!

期刊动态:2023年12月SCI、SSCI期刊目录更新 2023年12月19日,科睿唯安更新了WOS期刊目录,继上次11月WOS期刊目录剔除5本SCIE&SSCI期刊之后,此次12月更新又有5本期刊发生变动,其中有4本SCIE期刊被改名,1…

WIN10安装gurobi给matlab使用(记录)

https://www.gurobi.com/downloads/gurobi-software/ 这是以前的matlab路径,需要修改成新的 使用校园网激活一下 运行gurobi_setup Google报错信息,发现mathwork官方的解释是:找不到相关的dll文件,所以mex无效。 解决方案&…

司铭宇老师:电话销售技巧培训之如何提升电话销售技巧

电话销售是一项需要不断学习和提升技能的工作。无论你是刚刚进入这个行业的新手,还是已经有一些经验的销售人员,不断提高自己的电话销售技巧都是非常必要的。在本篇文章中,我将分享一些实用的技巧和案例,帮助大家更好地完成电话销…

重新配置torch1.8 cuda11.1 torchtext0.9.0虚拟Pytorch开发环境

这里写目录标题 起因发现选择安装cuda 11.1核对下自己的显卡是否支持下载该版本的CUDACUDA下载地址CUDA安装过程在anaconda中创建一个虚拟环境1.以下是环境的配置过程2.查看虚拟环境列表3.激活虚拟环境4.输入这句代码,没想到就可以直接安装torch和torchtext了[网站在…

【深度学习】语言模型与注意力机制以及Bert实战指引之一

文章目录 统计语言模型和神经网络语言模型注意力机制和Bert实战Bert-配置环境 统计语言模型和神经网络语言模型 区别:统计语言模型的本质是基于词与词共现频次的统计,而神经网络语言模型则是给每个词赋予了向量空间的位置作为表征,从而计算它…

如何让32位.Net 应用打开3G开关

昨天刚分享了《如何让.NET应用使用更大的内存》&#xff0c;结果就有同学说&#xff0c;<最好加一下32位如何开启大内存&#xff0c;因为很多传统项目32位&#xff0c;实在迁移不动了>&#xff0c;那么&#xff0c;我就验证了一些可行的方案&#xff0c;发现都挺简单的。…

力扣题:子序列-12.28

力扣题-12.28 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;521. 最长特殊序列 Ⅰ 解题思想&#xff1a;若两字符串不相同&#xff0c;可以选择较长的字符串作为最长特殊序列&#xff0c;显然它不会是较短的字符串的子序列。 class Solution(ob…

从零开始制作一个Douban图像下载器:Wt库的基础知识和操作指南

引言 欢迎来到本文&#xff0c;如果你希望从豆瓣下载海量的高清图像、学习使用现代C web应用程序框架Wt库开发web应用程序&#xff0c;或者了解如何利用代理IP和多线程技术提高爬虫效率和稳定性&#xff0c;那么你来对地方了。在接下来的内容中&#xff0c;我们将为你提供一个…

vue3 使用<script lang=“ts“ setup>加上lang=“ts“后编译错误

报错信息 报错原因 加上了langts解决 下载typescript和loader npm install typescript ts-loader --save-dev配置vue.config.js 添加下面的代码 configureWebpack: { resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }…