【可用性】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;@Resourceprivate RedisTemplate redisTemplate;/*** 项目启动时自动执行该方法* @param args* @throws Exception*/@Overridepublic 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中注册的所有服务实例idMap 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中剔除。

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

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

相关文章

CRM客户登记管理系统:企业数字化转型的必备工具

客户登记管理系统(CRM)是一种用于记录和管理客户信息的软件系统。它用于存储和跟踪客户的基本信息、联系方式、交易历史、服务请求等关键数据,以便企业能够更好地了解客户、提供个性化的服务,并进行有效的销售和营销活动。 CRM系统…

扫描电镜操作的注意点有哪些

扫描电子显微镜(SEM)是一种高分辨率的显微镜,用于观察微观尺度的表面形貌。在操作SEM时,需要注意一些关键的操作注意点,以确保获得高质量的显微图像和保护仪器的正常运行。以下是一些常见的扫描电子显微镜操作注意点&a…

STM32与Freertos入门(四)任务调度的介绍

简介: FreeRTOS支持的任务调度方法有抢占式、协作式、时间片轮转,下面分别来讲解。 1.抢占式调度 抢占式调度,是最高优先级的任务一旦就绪,总能得到CPU的执行权。 高优先级运行时候,低优先级不运行,等待…

【分治算法】运算的优先级

最典型的回溯算法就是归并排序,核心逻辑如下: public void sort(int[] nums, int lo, int ho){int mid (lo hi) / 2;//对数组的两部分分别排序sort(nums,lo, mid);sort(nums, mid1,hi);//合并两个排好序的子数组merge(nums, lo, mid, hi); }添加括号的…

uniapp 用于开发H5项目展示饼图,使用ucharts 饼图示例

先下载ucharts H5示例源码: uCharts: 高性能跨平台图表库,支持H5、APP、小程序(微信小程序、支付宝小程序、钉钉小程序、百度小程序、头条小程序、QQ小程序、快手小程序、360小程序)、Vue、Taro等更多支持canvas的框架平台&#…

企业电子招标采购系统源码Spring Cloud + Spring Boot + 前后端分离 + 二次开发

项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审…

sqlserver dba日常操作

文章目录 查询慢sql的方法sqlserver备份全备差异备日志备ldf备份事务备份 注意事项SQL Server 还原全备还原差异备份还原日志备/尾日志还原事务日志还原备份还原中的问题还原失败,需要某些权限重命名sql Server数据库名称失败 作业迁移单个迁移批量迁移 登陆账号迁移…

【工作流Activiti】流程实例

1、什么是流程实例 流程定义ProcessDefinition和流程实例ProcessInstance是Activiti重要的概念,类似于Java类和Java实例的关系 启动一个流程实例表示开始一次业务流程的运行,比如员工请假流程部署完成,如果张三要请假就可以启动一个流程实例…

PHP-PhpSpreadsheet导出带图片方法

需求描述 导出表格&#xff0c;项目名称对应项目详情页面二维码。 实现方法 1&#xff0c;先将各个项目生成的二维码存放到了一个指定目录里面&#xff1b; 2&#xff0c;导出数据到excel表格 <?phpuse PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpread…

Linux Centos 配置 Docker 国内镜像加速

在使用 Docker 进行容器化部署时&#xff0c;由于国外的 Docker 镜像源速度较慢&#xff0c;我们可以配置 Docker 使用国内的镜像加速器&#xff0c;以提高下载和部署的效率。本文将介绍如何在 CentOS 系统上配置 Docker 使用国内镜像加速。 步骤一&#xff1a;安装 Docker 首…

ubuntu16.04升级到ubuntu18.04

当您执行 sudo do-release-upgrade 但收到 “No new release found” 的消息时&#xff0c;这通常意味着系统没有检测到可用的升级。对于 Ubuntu 16.04 LTS 到 Ubuntu 18.04 LTS 的升级&#xff0c;您可能需要考虑以下几点&#xff1a; 1. 确保所有软件包都是最新的 再次运行…

视频推拉流EasyDSS互联网直播/点播平台构建户外无人机航拍直播解决方案

一、背景分析 近几年&#xff0c;国内无人机市场随着航拍等业务走进大众&#xff0c;出现爆发式增长。无人机除了在民用方面的应用越来越多&#xff0c;在其他领域也已经开始广泛应用&#xff0c;比如公共安全、应急搜救、农林、环保、交通 、通信、气象、影视航拍等。无人机使…

【C盘清理】Jetbrains全家桶(PyCharm、Clion……)更改 IDE 特定文件(配置、缓存、插件、日志等)存储位置

文章目录 一、官网说明二、更改 IDE 目录的位置1. 转到“帮助”|“编辑自定义属性”2. 各文件位置3. 以PyCharm系统目录为例4. 修改idea.properties 三、清理旧的 IDE 目录 一、官网说明 IDE 使用的目录官网说明 二、更改 IDE 目录的位置 默认情况下&#xff0c;PyCharm 将每…

硬件基础-二极管

3.二极管 正偏时是多数载流子载流导电&#xff0c;反偏时是少数载流子载流导电。所以&#xff0c;正偏电流大&#xff0c;反偏电流小&#xff0c;PN 结显示出单向电性。多数载流子正向通过 PN 结时就需要克服内电场的作用&#xff0c;需要约 0.7 伏的外加电压&#xff0c;这是…

Pytorch神经网络的参数管理

目录 一、参数访问 1、目标参数 2、一次性访问所有参数 3、从嵌套块收集参数 二、参数初始化 1、内置初始化 2、自定义初始化 3、参数绑定 在选择了架构并设置了超参数后&#xff0c;我们就进入了训练阶段。此时&#xff0c;我们的目标是找到使损失函数最小化的模型参数…

大数据技术15:大数据常见术语汇总

前言&#xff1a;大数据的出现带来了许多新的术语&#xff0c;但这些术语往往比较难以理解。因此&#xff0c;通过本文整理了大数据开发工程师经常会接触到的名词和概念&#xff0c;了解这些专有名词对于数据研发和数据分析时的人员协作及研发都有很高的作用。 一、数据中台相关…

原来Python的协程有2种实现方式

什么是协程 在 Python 中&#xff0c;协程&#xff08;Coroutine&#xff09;是一种轻量级的并发编程方式&#xff0c;可以通过协作式多任务来实现高效的并发执行。协程是一种特殊的生成器函数&#xff0c;通过使用 yield 关键字来挂起函数的执行&#xff0c;并保存当前的执行…

APM固件编译和仿真

事情起因 主要想对无人机APM固件进行仿真的算法验证&#xff0c;因实际飞行的过程实际验证太浪费飞机了&#xff0c;所以就先试用仿真对算法进行仿真开发。 一&#xff0c;环境搭建 环境搭建我建议参考官方英文教程&#xff0c;英文教程写的比较全&#xff0c;不懂可以自己使…

contentType及MIME类型详细说明

ContentType及 MIME详解 contentType 是用于指定 HTTP 请求或响应中主体数据的媒体类型&#xff08;Media Type&#xff09;或 MIME 类型&#xff08;Multipurpose Internet Mail Extensions&#xff09;。它通常作为请求头&#xff08;Request Header&#xff09;或响应头&am…

智能 GPT 图书馆又重生了

智能 GPT 图书馆又重生了 作者&#xff1a;程序员小白条 1&#xff09;概述 自从大二寒假准备开始筹备这个项目&#xff0c;到现在已经一年了&#xff0c;这个项目能维护一年&#xff0c;不愧是我.jpg。本来这个项目只是想练练手&#xff0c;因为那时候刚学完 Spring Boot2 V…