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

Feign实现微服务间远程调用续;基于Redis实现消息队列用于延迟任务的处理,Redis分布式锁的实现;(黑马头条Day05)

目录

延迟任务和定时任务

使用Redis设计延迟队列原理

点评项目中选用list和zset两种数据结构进行实现

如何缓解Redis内存的压力同时保证Redis中任务能够被正确消费不丢失

系统流程设计

使用Feign实现微服务间的任务消费以及文章自动审核

系统微服务功能介绍

提交文章->审核文章执行流程

Redis中SET NX实现分布式锁


延迟任务和定时任务

定时任务

        有固定周期,有明确的触发事件。

延迟任务

        没有固定的开始时间,它常常是由一个事件触发的,而在这个事件触发之后的一段时间内触发另一个事件,任务可以立即执行,也可以延迟一段时间后执行。参考如下:


        延迟任务的实现常常基于一个延迟队列,延迟队列的实现方案有:

        DelayQueue、RebbitMQ、Redis中基于Zset数据结构的实现。【本篇文章主要介绍项目中使用到的Redis实现的延迟队列,后续会将其他方法实现的延迟队列逐步完善总结】

使用Redis设计延迟队列原理

        Redis的基本数据结构中的Zset内部可以根据给定的权重对元素进行排序,随后使用

 stringRedisTemplate.opsForZSet().rangeByScore(key, min, max),对指定的Key寻找score在min-max间的元素。在向Zset中插入元素的时候可以将优先级设置为socre如果将时间作为优先级实现延迟队列,可以在插入元素同时获取当前系统时间作为socre,如果需要指定5min后执行,则将当前系统获取的时间+5min作为对应元素的socre值。实现基于Redis作为延迟队列。

点评项目中选用list和zset两种数据结构进行实现

        常规需求下基于Redis实现的延迟队列,只需要根据zset设置对应元素的score即可实现,如果进一步考虑数据量非常大的情况下此时时间复杂度比较高。在zset中分别使用zadd(.)以及zrange(.)的时间复杂度分别为:

  • ZADD时间复杂度O(M*logN):M成功添加的元素数,N是有序集合的基数。
  • ZRANGE:按照从低到高的顺序,获取指定排名范围内的成员。时间复杂度:O(log(N)+M),其中 N 是有序集合的基数,M 是指定排名范围内的成员数量。

        选用list和zset相结合的方式实现延迟队列,list中存储当前需要执行的任务,zset中存储需要延迟(未来执行)的任务此时向list的一端存储元素并从list的另一端取出元素,不仅可以保证任务消费的有序性,同时list中存储以及获取元素的时间复杂度均为O(1)在数据量大的情况下性能更优。 

如何缓解Redis内存的压力同时保证Redis中任务能够被正确消费不丢失

        Redis是基于内存的数据库,有一定的存储容量,可以采用Redis+MySQL相结合的方式。

  • 每次到达一个新的任务需要延迟消费时,首先将对应任务存储到MySQL数据中,其次将其根据消费时间(立马消费、延迟消费)存储到对应list或zset中。
  • 在任务被消费时,首先从Redis的list中获取元素进行消费,并将任务从Redis中删除,同时将对应的任务从MySQL数据库中进行删除,避免重复消费。
  • 任务需要消费时首先将其存储到MySQL中,随后将对应时间范围内(比如小于当前时间5min)存入到Redis中,时间大于规定范围的存储到MySQL数据库中,并且每消费一条Redis中的任务同时将MySQL中对应的任务清理。所以MySQL中存储的任务均是未消费的任务,使用定时任务从MySQL中提取任务并加载到Redis中进行消费,此操作必须先将Redis中的任务全部清空,避免相同的任务再次加载到Redis中被重复消费。
  • zset中存储的任务借助Spring Task框架提供的定时任务功能,按照一定时间间隔自动根据score提取对应范围的任务并将其加载到list中进行消费。

系统流程设计

使用Feign实现微服务间的任务消费以及文章自动审核

系统微服务功能介绍

  • ①:feign微服务:定义feign远程调用的接口。
  • ②:article微服务:app端数据存储,以及实现feign中定义的保存文章配置相关接口。
  • ③:schedule微服务:消息队列微服务,实现任务MySQL的记录以及Redis中任务的消费。同时实现feign中定义的调用延迟队列的接口。
  • ④:wemedia微服务:浏览器端/管理端实现,用于实现保存自媒体文章,调用sehedule微服务,实现任务延迟消费以及调用article微服务实现文章自动审核后保存app端文章相关信息。

为什么需要将延迟队列相关实现单独防止在一个微服务schedule中:

        提高复用性,如果将延迟队列实现防止在wemedia微服务中,直接进行调用可以省去不必要的远程调用过程或者MQ实现。同时出现如果其他微服务也需要使用到Redis实现的消息队列,此时需要重新实现,所以将其抽取为一个单独的微服务,提高复用性。

提交文章->审核文章执行流程

        可以参考SpringCloud Feign实现微服务间的远程调用(黑马头条Day04)-CSDN博客 的了解Feign的远程调用的简单原理。

  1. 自媒体发布文章,远程调用消息队列微服务,将任务存入消息(延迟)队列。
  2. 自媒体微服务通过远程调用定时拉取消息队列中的任务进行文章审核。
  3. 自媒体微服务审核完文章后调用app端相关微服务,将文章相关html页面对应的url路径等信息存入到文章相关数据表。

上图中有两个地方并没有画出:

  • 延迟队列微服务定期从zset中根据score范围取数据并放进list中进行消费。
  • 延迟队列微服务定期从MySQL数据库中加载未消费的任务到延迟队列。

贴两个小代码:

    /*** 定时刷新数据从ZSet到list中*/@Scheduled(cron = "0 */1 * * * ?")public void refresh(){// 添加分布式锁String token = cacheService.tryLock("FUTURE_TASK_SYNC", 1000 * 30);if(StringUtils.isNotBlank(token)){log.info("启动定时刷新任务,当前时间为:{}", System.currentTimeMillis() / 1000);// 获取所有未来数据的集合的keySet<String> fututrKeys = cacheService.scan(ScheduleConstants.FUTURE + "*");for (String fututrKey : fututrKeys) {// 根据futureKey计算topicKeyString topicKey = ScheduleConstants.TOPIC + fututrKey.split(ScheduleConstants.FUTURE)[1];// 获取该组key下需要消费的数据Set<String> tasks = cacheService.zRangeByScore(fututrKey, 0, System.currentTimeMillis());// 将需要消费的任务添加list中if(!tasks.isEmpty()){cacheService.refreshWithPipeline(fututrKey, topicKey, tasks);log.info("成功的将{}对应的数据刷新到{}中", fututrKey, topicKey);}}}}/*** 定时加载数据库中的数据到Redis中*/@PostConstruct  // 开启即加载@Scheduled(cron = "0 */5 * * * ?")public void reloadData(){// 清理缓存中的数据clearCache();// 查询数据库中数据,根据执行时间小于当前时间5min// 获取5分钟后的时间Calendar calendar = Calendar.getInstance();calendar.add(Calendar.MINUTE, 5);List<Taskinfo> taskinfos = taskinfoMapper.selectList(Wrappers.<Taskinfo>lambdaQuery().lt(Taskinfo::getExecuteTime, calendar.getTime()));if(taskinfos != null && taskinfos.size() > 0){// 将查询的数据添加到缓存中for (Taskinfo taskinfo : taskinfos) {Task task = new Task();BeanUtils.copyProperties(taskinfo, task);task.setExecuteTime(taskinfo.getExecuteTime().getTime());addTaskToRedis(task);log.info("添加任务到Redis中:{}", task);}}}/*** 清理缓存中的数据*/private void clearCache() {Set<String> topicKey = cacheService.scan(ScheduleConstants.TOPIC + "*");Set<String> futureKey = cacheService.scan(ScheduleConstants.FUTURE + "*");cacheService.delete(topicKey);cacheService.delete(futureKey);}

Redis中SET NX实现分布式锁

        为什么需要分布式锁:控制分布式系统有序的去对共享资源进行操作,通过互斥来保证数据的一致性。考虑以下场景,如果两个延迟队列微服务同时从zset中刷新未来要执行的任务到list中,由于两个微服务设置的定时时间都一样,此时会出现共享变量的重复操作。

         使用Redis实现的分布式锁保证同一时刻只有一个微服务操作共享资源。

sexnx (SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值。

这种加锁的思路是,如果 key 不存在则为 key 设置 value,如果 key 已存在则 SETNX 命令不做任何操作

  • 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

  • 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

  • 客户端A执行代码完成,删除锁

  • 客户端B在等待一段时间后再去请求设置key的值,设置成功

  • 客户端B执行代码完成,删除锁

可以参考Redission实现的分布式锁:Redis分布式锁实现-CSDN博客。

暂时写到这里,有时间再补.....

相关文章:

Feign实现微服务间远程调用续;基于Redis实现消息队列用于延迟任务的处理,Redis分布式锁的实现;(黑马头条Day05)

目录 延迟任务和定时任务 使用Redis设计延迟队列原理 点评项目中选用list和zset两种数据结构进行实现 如何缓解Redis内存的压力同时保证Redis中任务能够被正确消费不丢失 系统流程设计 使用Feign实现微服务间的任务消费以及文章自动审核 系统微服务功能介绍 提交文章-&g…...

CSS 常见属性设置

一. 文本属性 1.1. 装饰线 text-decoration text-decoration有如下常见取值: none&#xff1a;无任何装饰线&#xff08;可以去除a元素默认的下划线&#xff09;underline&#xff1a;下划线overline&#xff1a;上划线line-through&#xff1a;中划线&#xff08;删除线&…...

docker学习入门

1、docker简介 docker官网&#xff1a; www.docker.com dockerhub官网&#xff1a; hub.docker.com docker文档官网&#xff1a;docs.docker.com Docker是基于Go语言实现的云开源项目。 Docker的主要目标是&#xff1a;Build, Ship and Run Any App, Anywhere(构建&…...

蓝牙系列七:开源蓝牙协议栈BTStack数据处理

继续蓝牙系列的研究。 在上篇博客,通过阅读BTStack的源码,大体了解了其框架,对于任何一个BTStack的应用程序都有一个main函数,这个main函数是统一的。这个main函数做了某些初始化之后,最终会调用到应用程序提供的btstack_main,在btstack_main里面首先做一些初始化,然后…...

数据仓库作业一:第1章 绪论

目录 一、给出下列英文短语或缩写的中文名称&#xff0c;并简述其含义。二、简述操作型数据与分析型数据的主要区别。三、简述数据仓库的定义。四、简述数据仓库的特征。五、简述主题的定义。六、简述元数据的概念。七、简述数据挖掘的主要任务。八、简述数据挖掘的主要步骤。九…...

spring aop中获取request和response

Spring AOP 操作中如何使用request和response 实际使用时&#xff0c;如果方法一不行&#xff0c;请使用方法二 方法一 HttpServletRequest request ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletResponse respons…...

在Mac上安装nginx+rtmp 本地服务器

需要使用终端命令&#xff0c;如果没有Homebrew&#xff0c;要安装Homebrew,执行&#xff1a; ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 一、安装Nginx 1、先clone Nginx项目到本地&#xff1a; brew tap de…...

解决ChatGPT发送消息没有反应

ChatGPT发消息没反应 今天照常使用ChatGPT来帮忙码代码&#xff0c;结果发现发出去的消息完全没有反应&#xff0c;即不给我处理&#xff0c;也没有抱任何的错误&#xff0c;按浏览器刷新&#xff0c;看起来很正常&#xff0c;可以查看历史对话&#xff0c;但是再次尝试还是一…...

windows关闭copilot预览版

如果用户不想在windows系统当中启用Copilot&#xff0c;可以通过以下三种方式禁用。 第一种&#xff1a;隐藏Copilot 按钮 右键点击任务栏&#xff0c;取消勾选“显示 Copilot&#xff08;预览版&#xff09;按钮”&#xff0c;任务栏则不再显示&#xff0c;用户可以通过快捷键…...

基于Java的社区买菜系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.1.1 数据中心模块2.1.2 菜品分类模块2.1.3 菜品档案模块2.1.4 菜品订单模块2.1.5 菜品收藏模块2.1.6 收货地址模块 2.2 可行性分析2.3 用例分析2.4 实体类设计2.4.1 菜品分类模块2.4.2 菜品档案模块2.4.3…...

html--心花怒放

代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Canvas 绘制一个❤</title><link rel"shortcut icon" href"../../assets/images/icon/favicon.ico" type"ima…...

FPGA的配置状态字寄存器Status Register

目录 简介 状态字定义 Unknown Device/Many Unknow Devices 解决办法 一般原因 简介 Xilinx的FPGA有多种配置接口&#xff0c;如SPI&#xff0c;BPI&#xff0c;SeletMAP&#xff0c;Serial&#xff0c;JTAG等&#xff1b;如果从时钟发送者的角度分&#xff0c;还可以…...

【HarmonyOS Arkts笔记】http网络请求封装

common.ts export default class CommonConstant {/*** The host address of the server.*/static readonly SERVER: string 请求接口地址;/*** The request success code.*/static readonly SUCCESS_CODE: number 200;/*** Read timeout.*/static readonly READ_TIMEOUT: n…...

html前端的几种加密/解密方式

HTML前端的加密解密方式有以下几种&#xff1a; 一、base64加密 Base64编码&#xff1a;Base64是一种将二进制数据转换为可打印字符的编码方式。在前端&#xff0c;可以使用JavaScript的btoa()函数进行Base64编码&#xff0c;使用atob()函数进行解码。 var str "hello…...

算法学习01:排序二分

算法学习01&#xff1a;排序&&二分 文章目录 算法学习01&#xff1a;排序&&二分前言需要记忆的模版&#xff1a;快速排序归并排序&#xff1a;整数二分&#xff1a;浮点数二分 一、排序1.快速排序2.归并排序&#xff1a; 二、二分1.整数2.浮点数 总结 前言 需要…...

OpenAI (ChatGPT)中国免费试用地址

GitHub - click33/chatgpt---mirror-station-summary: 汇总所有 chatgpt 镜像站&#xff0c;免费、付费、多模态、国内外大模型汇总等等 持续更新中…… 个人能力有限&#xff0c;搜集到的不多&#xff0c;求大家多多贡献啊&#xff01;众人拾柴火焰高&#xff01;汇总所有 cha…...

IOS面试题object-c 11-20

11、解释self [super init]方法&#xff1f; 容错处理, 当父类初始化失败,会返回一个nil, 表示初始化失败。 由于继承的关系, 子类是需要拥有父类的实例和行为, 因此, 我们必须先初始化父类,然后再初始化子类 12、简述使用block有什么优点&#xff1f;代码紧凑&#xff0c;传值…...

北斗导航 | 十四种抗差稳健估计(抗差M估计)方法(算法公式)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 稳健估计(M估计) 1、Huber法2、残差绝对和最小法3、L1-L2法...

【JavaEE】_Spring MVC项目使用数组与集合传参

目录 1. 使用数组传参 1.2 传递单个参数 1.3 传递多个名称相同的参数 1.3.1 关于urlencode 2. 使用集合传参 1. 使用数组传参 创建一个Spring MVC项目&#xff0c;其中 .java文件内容如下&#xff1a; package com.example.demo.controller;import com.example.demo.Per…...

Centos 9 安装 k8s

为了尽可能契合生产环境的部署情况&#xff0c;这里用kubeadm安装集群&#xff0c;同时方便跟随笔记一步步实践的过程&#xff0c;也更加了解k8s的一些特性和基础知识。 先决条件 这里将通过虚拟机安装3台centos stream 9服务器&#xff0c;并组成kubeneters集群&#xff08;…...

告别示波器抓瞎:手把手教你用低成本逻辑分析仪解码汽车SENT传感器信号

低成本逻辑分析仪破解汽车SENT传感器全指南 当发动机故障灯突然亮起&#xff0c;4S店用专业设备检测后告诉你"某个传感器信号异常"时&#xff0c;你是否好奇过这些隐藏在金属外壳下的数据究竟如何传递&#xff1f;在汽车电子领域&#xff0c;SENT协议正逐渐成为压力…...

安信可ESP8266 AT固件连接自建MQTT服务器实战:从烧录到订阅发布的完整避坑指南

安信可ESP8266 AT固件连接自建MQTT服务器实战&#xff1a;从烧录到订阅发布的完整避坑指南 在物联网设备开发中&#xff0c;MQTT协议因其轻量级和高效性成为设备与服务器通信的首选方案。安信可ESP8266模块搭配AT固件&#xff0c;为开发者提供了一种快速实现MQTT连接的解决方案…...

DeepSeek总结的PostgreSQL MVCC,逐字节解析

来源&#xff1a;https://boringsql.com/posts/postgresql-mvcc-byte-by-byte/ PostgreSQL MVCC&#xff0c;逐字节解析 2026-04-17 Radim Marek 你在一个 psql 会话中运行 SELECT * FROM orders&#xff0c;看到了 5000 万行。你的同事在另一个会话中同时运行相同的查询&a…...

PTA天梯赛L2通关秘籍:从链表去重到彩虹瓶,这10道模拟题帮你避开所有坑

PTA天梯赛L2模拟题深度解析&#xff1a;从解题框架到实战技巧 在算法竞赛的世界里&#xff0c;PTA天梯赛作为国内最具影响力的程序设计赛事之一&#xff0c;其L2级别的题目往往成为选手晋级的关键门槛。而其中占比高达70%的模拟类题型&#xff0c;更是检验选手编程基本功和逻辑…...

DNS = IP?

答案是&#xff1a;不等于。 这是一个典型的**“名字”与“地址”**的混淆。 DNS (Domain Name System) 是电话簿&#xff08;查询系统/协议&#xff09;。IP (Internet Protocol Address) 是电话号码&#xff08;具体地址/标识符&#xff09;。域名 (Domain Name) 是联系人姓名…...

如何快速创建专业条码:开源字体完整指南

如何快速创建专业条码&#xff1a;开源字体完整指南 【免费下载链接】librebarcode Libre Barcode: barcode fonts for various barcode standards. 项目地址: https://gitcode.com/gh_mirrors/li/librebarcode 你知道吗&#xff1f;生成专业条码可以像打字一样简单&…...

VSAN集群安全关机与重启实战指南

1. VSAN集群安全关机与重启的核心挑战 第一次接触VSAN集群关机流程时&#xff0c;我也犯过直接断电的低级错误。那是在测试环境里&#xff0c;四台ESXi主机同时断电后&#xff0c;整个VSAN存储池直接崩溃&#xff0c;花了整整两天时间才恢复数据。这次惨痛教训让我明白&#xf…...

终极键盘鼠标控制器:Mouseable如何彻底改变你的工作效率

终极键盘鼠标控制器&#xff1a;Mouseable如何彻底改变你的工作效率 【免费下载链接】mouseable Mouseable is intended to replace a mouse or trackpad. 项目地址: https://gitcode.com/gh_mirrors/mo/mouseable 在当今数字化工作环境中&#xff0c;鼠标已经成为我们日…...

终极Win11优化指南:用Win11Debloat让系统重获新生

终极Win11优化指南&#xff1a;用Win11Debloat让系统重获新生 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and custom…...

MCE丨重组蛋白融合标签:从设计到纯化的实战指南

1. 重组蛋白融合标签的设计策略 刚开始接触重组蛋白表达时&#xff0c;我也曾被各种融合标签搞得晕头转向。直到在实验室熬了三个通宵纯化失败后&#xff0c;才真正明白标签设计的重要性。融合标签就像给蛋白质装上的"导航仪"&#xff0c;不仅能帮我们快速找到目标蛋…...