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

基于redis的定时状态更新

基于redis的定时状态更新

下面是一个简单的示例,展示如何使用redis实现状态更新,从而满足在某些场景下,既需要频繁更新状态,
又需要保证状态的实时性。以及定时更新状态的需求。

示例说明

  1. 假设有一个剧目演出计划,确定了剧目演出的开始和结束时间
  2. 演出状态分为:未开始、进行中、已结束(分别对应0、1、2三个枚举)
  3. 需要定时更新状态,根据当前时间判断状态是否需要更新
  4. 定期删除已经结束的剧目演出计划

实现

//  该做法也可以用于订单超时自动取消等场景,通过设置过期时间和处理过期事件,实现订单状态的自动更新。package mainimport ("context""fmt""github.com/redis/go-redis/v9""sync""time"
)var rdb = redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "123456", // 确保 Redis 密码正确DB:       6,        // 与订阅的数据库一致
})func initPerformanceStatus(ctx context.Context, performanceID string) error {key := fmt.Sprintf("plan:%s", performanceID) // 初始键名为 "plan:01"return rdb.Set(ctx, key, "0", 0).Err()
}func startPerformance(ctx context.Context, performanceID string, duration time.Duration) error {key := fmt.Sprintf("plan:%s", performanceID) // 过期键名仍为 "plan:01"return rdb.SetEx(ctx, key, "1", duration).Err()
}func handleExpiredKey(ctx context.Context, msg *redis.Message) {// 直接使用过期键名(如 "plan:01",与设置时一致)expiredKey := string(msg.Payload)fmt.Printf("处理过期键:%s\n", expiredKey) // 新增调试日志// 更新状态为 2(直接操作原键,无需重新拼接前缀)err := rdb.Set(ctx, expiredKey, "2", 0).Err()if err != nil {fmt.Printf("更新失败:%v\n", err)} else {fmt.Printf("状态更新为 2:%s\n", expiredKey)}
}func main() {fmt.Println("主线程开始运行...")wg := &sync.WaitGroup{}wg.Add(1)go hook(wg)fmt.Println("主线程继续运行, 进行其他工作...")wg.Wait()
}func hook(wg *sync.WaitGroup) {defer wg.Done()ctx := context.Background()// 每隔 1 分钟检查一次过期键(演出状态为"2")CheckExpiredKeys(1)// 1. 确保键空间通知配置正确(先获取当前配置,避免重复设置)config, err := rdb.ConfigGet(ctx, "notify-keyspace-events").Result()if err != nil || config["1"] != "Ex" {if err := rdb.ConfigSet(ctx, "notify-keyspace-events", "Ex").Err(); err != nil {fmt.Printf("配置通知失败:%v\n", err)return}}// 2. 初始化并启动演出performanceID := "01"if err := initPerformanceStatus(ctx, performanceID); err != nil {fmt.Printf("初始化失败:%v\n", err)return}fmt.Println("初始化完成,等待演出开始...")fuTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2025-05-08 13:17:50", time.Local)if err != nil {fmt.Printf("解析时间失败:%v\n", err)return}timestamp := fuTime.Unix() - time.Now().Unix()fmt.Printf("距离演出开始还有 %d 秒\n", timestamp)fuTime2, err := time.ParseInLocation("2006-01-02 15:04:05", "2025-05-08 13:18:00", time.Local)if err != nil {fmt.Printf("解析时间失败:%v\n", err)return}timestamp2 := fuTime2.Unix() - time.Now().Unix()fmt.Printf("演出前距离演出结束还有 %d 秒\n", timestamp2)sub := timestamp2 - timestampfmt.Printf("演出后距离演出结束还有 %d 秒\n", sub)time.AfterFunc(time.Duration(timestamp)*time.Second, func() {if err := startPerformance(ctx, performanceID, time.Duration(sub)*time.Second); err != nil { // 缩短过期时间便于测试fmt.Printf("启动演出失败:%v\n", err)return}fmt.Println("演出已开始,等待结束...")})// 3. 订阅当前数据库(6)的过期事件pubSub := rdb.Subscribe(ctx, fmt.Sprintf("__keyevent@%d__:expired", 6)) // 动态生成数据库编号defer func(pubSub *redis.PubSub) {err := pubSub.Close()if err != nil {fmt.Printf("关闭订阅失败:%v\n", err)}}(pubSub)// 4. 阻塞接收事件(移除协程,简化逻辑便于调试)for {msg, err := pubSub.ReceiveMessage(ctx)if err != nil {fmt.Printf("接收消息失败:%v\n", err)break}handleExpiredKey(ctx, msg) // 直接处理,避免协程导致的并发问题}
}// 定时任务,用于检查过期键并更新状态
func CheckExpiredKeys(minute int64) {// 1. 初始化定时任务(每隔 minute 分钟执行一次)interval := time.Duration(minute) * time.Minute // 可通过配置修改ticker := time.NewTicker(interval)defer ticker.Stop() // 程序退出时停止 Ticker// 2. 在 goroutine 中执行定时任务go func() {for range ticker.C { // 阻塞直到间隔到达fmt.Printf("开始执行定时任务(当前时间:%s)\n", time.Now().Format("2006-01-02 15:04:05"))ctx := context.Background()// 遍历所有演出键,检查是否为过期键keys, err := rdb.Keys(ctx, "plan:*").Result()if err != nil {panic(err)}for _, key := range keys {v, err := rdb.Get(ctx, key).Result()if err != nil {panic(err)}if v != "2" {continue}// 过期删除rdb.Del(ctx, key)}}}()
}

适用场景

  1. 状态更新频繁,且需要实时性的场景
  2. 定时更新状态的需求,如订单超时自动取消等场景

相关文章:

基于redis的定时状态更新

基于redis的定时状态更新 下面是一个简单的示例,展示如何使用redis实现状态更新,从而满足在某些场景下,既需要频繁更新状态, 又需要保证状态的实时性。以及定时更新状态的需求。 示例说明 假设有一个剧目演出计划,确…...

[原创](现代Delphi 12指南):[macOS 64bit App开发]: 如何获取自身程序的所在的目录?

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

服务器托管的常见问题

一、何谓IDC服务器托管服务? IDC服务器托管是指为了提高网站的访问速度,将您的服务器及相关设备托管到具有完善机房设施、高品质网络环境、丰富带宽资源和运营经验以及可对用户的网络和设备进行实时监控的网络数据中心内,以此使系统达到安全、可靠、稳定…...

使用Scrapeless Scraping Browser的自动化和网页抓取最佳实践

引言:人工智能时代浏览器自动化和数据收集的新范式 随着生成性人工智能、人工智能代理和数据密集型应用程序的快速崛起,浏览器正在从传统的“用户互动工具”演变为智能系统的“数据执行引擎”。在这一新范式中,许多任务不再依赖单一的API端点…...

电子电气架构 --- 如何有助于提安全性并减少事故

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...

【训练】Qwen2.5VL 多机多卡 Grounding Box定位

之前的相关文章: 【深度学习】LLaMA-Factory微调sft Qwen2-VL进行印章识别 https://www.dong-blog.fun/post/1661 使用LLaMA-Factory微调sft Qwen2-VL-7B-Instruct https://www.dong-blog.fun/post/1762 构建最新的LLaMA-Factory镜像 https://www.dong-blog.f…...

MYSQL的行级锁到底锁的是什么东西

MySQL 的行级锁是一种锁机制,它允许数据库在执行并发操作时,锁定表中的某一行数据而不是整张表。行级锁通过限制对特定行的访问,允许其他线程并发地访问表中的其他行,从而提高并发性和性能。 行级锁的锁定对象 行级锁锁定的是 行…...

图神经网络中的虚拟节点

1.虚拟节点 当我们使用节点来构成图结构时, regular node: 常规的节点即代表了某一个局部特征, 即局部节点特征。 virtual node: 普通的节点不同,有时会需要这样的一种特征, 该特征代表了该样本的全局信息&#xff0…...

关于多版本CUDA共存的研究,是否能一台机子装两个CUDA 版本并正常切换使用

我发现了一个很有意思的事 我装了11.8cuda再装12.3cuda结果我的11.8cuda还在,没被替换掉或者删掉 然后我打开我的环境发现它的环境除了cuda_path都没改 这样我就有个大胆的想法,如果我把cuda path换成11.8路径那是不是就能切换了 而且cuda_path 和 cuda_…...

el-table与echarts图形实现滚动联动

el-table与echarts图形滚动联动 效果图 实现思路 设计图滚动条位于表格下方,且echarts滚动不易获取当前展示数据到左侧的距离 故:通过监听表格的滚动实现联动 为了保持echarts的横坐标和表格的列基本保持对齐,用tdWidth标识单列表格的宽度…...

【Git】【commit】查看未推送的提交查看指定commit的修改内容合并不连续的commit

文章目录 1. 查看未推送的提交方法一 :git status方法二:git log方法三:git cherry方法四:git rev-list 2. 查看指定commit的修改方法一:git show方法二:git log方法三:git diff 3. 合并不连续的…...

C++GO语言微服务基础技术①

目录 01-项目简介 02-单体式架构 03-微服务优缺点 04-单体式和微服务区别 05-RPC简介 06-RPC使用步骤 07-注册RPC服务函数接口 08-绑定服务和调用方法函数接口 09-rpc服务端和客户端编码实现 10-json的rpc 11-rpc的封装 12-rpc封装小结 01-项目简介 # 单体式和微服…...

AI CUBE 使用指南 目标检测格式范例 AI cube 报错数据集不合规范,请清洗数据集

血的教训:labels.txt里面放1 2 3 4 ..也可以英文,不能有中文 教程:K230 借助 AICube部署AI 视觉模型 YOLO等教程_嘉楠 ai cube多标签分类-CSDN博客 | 目标检测范例: 不清楚不是数字行不行 这个id可以英文,你…...

vue中scss使用js的变量

一、前言 在项目开发中,很多时候会涉及到scss样式变量,正常定义方式 $primary-color: rgb(188, 0, 194);;使用时直接使用即可:color: $primary-color。但是,如果,这些变量是在js中定义的怎么办 二、实现 …...

QtGUI模块功能详细说明, 字体和文本渲染(四)

目录 一. 窗口和屏幕管理 二. 绘图和渲染 三. 图像处理 四. 字体和文本 1、核心概念 1.1、字体 (Font) 1.2、字形 (Glyph) 1.3、字符 (Character) 1.4、文本布局 (Text Layout) 1.5、文本渲染 (Text Rendering) 1.6、度量 (Metrics) 2、字体管理 2.1、QFont&#…...

计算机学习路线与编程语言选择(信息差)

——授人以鱼不如授人以渔 面向岗位学习!到招聘网站看看有哪些岗位,看一看岗位职责、要求 牛客网(计算机实习工作最好的网站) boss直聘 确定岗位后(如前端、后端),岗位需要什么语言&#xf…...

多环串级PID

文章目录 为什么要多环程序主函数内环外环 双环PID调参内环Kp调法Ki调法 外环Kp 以一定速度到达指定位置封装 为什么要多环 单环只能单一控制速度或者位置,如果想要同时控制多个量如速度,位置,角度,就需要多个PID 速度环一般PI…...

编写大模型Prompt提示词方法

明确目标和任务 // 调用LLM进行分析const prompt 你是一名严格而友好的英语口语评分官,专业背景包括语音学(phonetics)、二语习得(SLA)和自动语音识别(ASR)。你的任务是: ① 比对参…...

使用chrome浏览器截长图

如何使用chrome浏览器截长图: 使用chrome截取完整网页图片 第一步、按F12,开发者模式的布局按下图布局 第二步、按ctrlshiftp组合键,搜索“截图” ,然后自动截图保存在下载目录(右上角)了。...

【MySQL】第二弹——MySQL表的增删改查(CURD))

文章目录 🎓一. CRUD🎓二. 新增(Create)🎓三. 查询(Rertieve)📖1. 全列查询📖2. 指定列查询📖3. 查询带有表达式📖4. 起别名查询(as )📖 5. 去重查询(distinct)📖6. 排序…...

Android NDK版本迭代与FFmpeg交叉编译完全指南

在Android开发中,使用NDK(Native Development Kit)进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时。本文将深入分析Android NDK的版本迭代分界线,详细讲解FFmpeg交叉编译的注意事项,并提供完整的…...

【Linux网络】Socket-UDP相关函数

socket() 函数 这个函数的作用是创建一个 Socket 文件描述符&#xff0c;在客户端和服务器都可以使用。 #include <sys/socket.h> int socket(int domain, int type, int protocol);参数&#xff1a; domain&#xff1a;指定协议族&#xff0c;例如 AF_INET 代表 IPv4 …...

最优化方法Python计算:有约束优化应用——线性Lasso回归预测器

实际应用中&#xff0c;特征维度 n n n通常远大于样本容量 m m m&#xff08; n ≪ m n\ll m n≪m&#xff09;&#xff0c;这种高维小样本场景下特征数据可能含有对标签数据 y i y_i yi​的取值不必要的成分&#xff0c;甚至是噪声。此时&#xff0c;我们希望回归模型中的优化…...

基础算法 —— 二分算法 【复习总结】

1. 简介 1.1 原理 二分算法&#xff0c;顾名思义&#xff0c;关键在于二分&#xff0c;当我们求解的目标具有二段性时&#xff0c;我们就可以使用二分算法&#xff1a; 先根据待查找区间中点位置&#xff0c;判断结果会在左侧还是右侧&#xff0c;接下来&#xff0c;舍弃一半…...

计算机网络常识:缓存、长短连接 网络初探、URL、客户端与服务端、域名操作 tcp 三次握手 四次挥手

缓存&#xff1a; 缓存是对cpu&#xff0c;内存的一个节约&#xff1a;节约的是网络带宽资源 节约服务器的性能 资源的每次下载和请求都会造成服务器的一个压力 减少网络对资源拉取的延迟 这个就是浏览器缓存的一个好处 表示这个html页面的返回是不要缓存的 忽略缓存 需要每次…...

OpenHarmony平台驱动开发(九),MIPI DSI

OpenHarmony平台驱动开发&#xff08;九&#xff09; MIPI DSI 概述 功能简介 DSI&#xff08;Display Serial Interface&#xff09;是由移动行业处理器接口联盟&#xff08;Mobile Industry Processor Interface (MIPI) Alliance&#xff09;制定的规范&#xff0c;旨在降…...

经济体制1

一&#xff0e;计划经济体制与市场经济体制 1.计划经济又称指令型经济&#xff0c;是对生产和资源分配以及产品消费事先进行计划的经济体制。 市场经济体制是指依靠市场手段对资源进行配置的经济体制 注意&#xff1a; 计划与市场都是调节经济的手段&#xff0c;都属于资源配…...

Spring AI 入门(持续更新)

介绍 Spring AI 是 Spring 项目中一个面向 AI 应用的模块&#xff0c;旨在通过集成开源框架、提供标准化的工具和便捷的开发体验&#xff0c;加速 AI 应用程序的构建和部署。 依赖 <!-- 基于 WebFlux 的响应式 SSE 传输 --> <dependency><groupId>org.spr…...

[ctfshow web入门] web58

信息收集 if(isset($_POST[c])){$c $_POST[c];eval($c); }else{highlight_file(__FILE__); }这麽简单&#xff1f; 解题 好吧&#xff0c;还是我想得太简单了 把system禁用了。不是参数过滤&#xff0c;而是直接禁用&#xff0c;不管是间接还是直接调用system都不行&#x…...

Python量化交易Backtrader技术指标的实现

一、Backtrader技术指标概览 (一)Backtrader内置指标的优势 Backtrader内置的技术指标具有以下优势: 多样性:涵盖了常见的移动平均线、相对强弱指数(RSI)、布林带等多种指标,满足了不同交易者的需求。易用性:通过简单的函数调用即可在策略中添加和使用这些指标,无需…...

蓝桥杯第十六届c组c++题目及个人理解

本篇文章只是部分题目的理解&#xff0c;代码和思路仅供参考&#xff0c;切勿当成正确答案&#xff0c;欢迎各位小伙伴在评论区与博主交流&#xff01; 题目&#xff1a;2025 题目解析 核心提取 要求的数中至少有1个0、2个2、1个5 代码展示 #include<iostream> #incl…...

ARM 芯片上移植 Ubuntu 操作系统详细步骤

一、准备工作 &#xff08;一&#xff09;硬件准备 ARM 开发板&#xff1a;确保 ARM 开发板的型号与 Ubuntu 官方支持的 ARM 架构兼容&#xff0c;常见的 ARM 架构有 ARMv7、ARMv8 等。例如树莓派系列开发板&#xff0c;广泛用于 ARM 系统移植&#xff0c;其采用 ARM 架构。存…...

能耗优化新引擎:EIOT平台助力企业降本增效

安科瑞顾强 数字化转型的背景下&#xff0c;能源管理正加速向智能化、远程化方向演进。安科瑞电气推出的EIOT托管平台及ADW300系列4G无线计量仪表&#xff0c;通过云端技术与无线通信的深度融合&#xff0c;为用户打造了高效、便捷的远程能源监测与管理体系&#xff0c;助力企…...

录播课视觉包装与转化率提升指南

1. 封面设计黄金法则 1.1 程序员审美三要素 极客风配色方案 主色&#xff1a;深空灰(#2D2D2D) 代码蓝(#007BFF) 点缀色&#xff1a;终端绿(#28A745) 警告黄(#FFC107) 信息密度控制 核心标语≤9字&#xff08;如&#xff1a;"3天攻克分布式事务"&#xff09; 技…...

Solidity语言基础:区块链智能合约开发入门指南

一、Solidity概述 Solidity是以太坊生态系统中最重要的智能合约编程语言&#xff0c;由Gavin Wood于2014年提出。作为面向合约的高级语言&#xff0c;它结合了JavaScript、Python和C的语法特点&#xff0c;专为在以太坊虚拟机&#xff08;EVM&#xff09;上运行而设计。 核心…...

QMK开发环境搭建指南:Eclipse和VS Code详解

QMK开发环境搭建指南&#xff1a;Eclipse和VS Code详解 前言 各位键盘DIY爱好者们&#xff0c;今天跟大家分享如何搭建QMK固件开发环境。无论你是想定制自己的客制化键盘固件&#xff0c;还是对开源键盘固件开发感兴趣&#xff0c;这篇教程都能帮你搞定开发环境配置。本文将详…...

Python pandas 向excel追加数据,不覆盖之前的数据

最近突然看了一下pandas向excel追加数据的方法&#xff0c;发现有很多人出了一些馊主意&#xff1b; 比如用concat,append等方法&#xff0c;这种方法的会先将旧数据df_1读取到内存&#xff0c;再把新数据df_2与旧的合并&#xff0c;形成df_new,再覆盖写入&#xff0c;消耗和速…...

spring中RequestContextHolder

1、在 Spring 框架中&#xff0c; RequestAttributes attributes RequestContextHolder.getRequestAttributes(); 是获取当前请求上下文的核心方法。以下是其关键要点及注意事项&#xff1a; ‌一、核心机制‌ ‌作用原理‌ 通过 ThreadLocal 存储当前线程的请求属性对象 …...

Kotlin 遍历

在 Kotlin 中&#xff0c;遍历&#xff08;迭代&#xff09;是操作集合、数组、范围&#xff08;Range&#xff09;等数据结构的常见需求。Kotlin 提供了多种遍历方式&#xff0c;语法简洁且功能强大。以下是不同场景下的遍历方法总结&#xff0c;附代码示例&#xff1a; 一、…...

Ubuntu Linux系统配置账号无密码sudo

在Linux系统中&#xff0c;配置无密码sudo可以通过修改sudoers文件来实现。以下是具体的配置步骤 一、编辑sudoers文件 输入sudo visudo命令来编辑sudo的配置文件。visudo是一个专门用于编辑sudoers文件的命令&#xff0c;它会在保存前检查语法错误&#xff0c;从而防止可能的…...

C# NX二次开发:判断两个体是否干涉和获取系统日志的UFUN函数

大家好&#xff0c;今天要讲关于如何判断两个体是否干涉和获取系统日志的UFUN函数。 &#xff08;1&#xff09;UF_MODL_check_interference&#xff1a;这个函数的定义为根据单个目标体检查每个指定的工具体是否有干扰。 Defined in: uf_modl.h Overview Checks each sp…...

若依项目图片显示问题

图片显示异常问题 路径配置问题&#xff1a;前端图片路径配置错误&#xff0c;最初使用相对路径且未从根目录开始解析&#xff0c;导致浏览器根据当前页面 URL 解析路径出错。例如在用户信息展示页面&#xff0c;若当前页面 URL 为http://localhost:8088/user/profile&#xff…...

线索二叉树

一 概念 线索二叉树&#xff08;Threaded Binary Tree&#xff09;是一种对二叉树的优化结构&#xff0c;主要解决传统二叉树遍历时需要借助栈或递归&#xff08;额外空间开销&#xff09;的问题。通过利用节点中的空指针&#xff08;nullptr&#xff09;存储遍历过程中的前驱…...

Git查看某个commit的改动

在Git中查看特定commit的改动有多种方法&#xff0c;下面是几种常用的命令行方式&#xff1a; 1. 使用 git show 命令 这是最常用的方法&#xff0c;直接显示某个commit的详细信息和改动&#xff1a; git show <commit-hash> 例如&#xff1a; git show abc1234 也可…...

es 里的Filesystem Cache 理解

文章目录 背景问题1&#xff0c;Filesystem Cache 里放的是啥问题2&#xff0c;哪些查询它们会受益于文件系统缓存 问题3 查询分析 背景 对于es 优化来说常常看到会有一条结论给&#xff0c;给 JVM Heap 最多不超过物理内存的 50%&#xff0c;且不要超过 31GB&#xff08;避免…...

2025年3月电子学会等级考试五级题——4、收费站在哪里

文章目录 题目代码公式小结 题目 4、收费站在哪里 在一条高速公路上&#xff0c;如果已知 n 座收费站的位置 x1,x2,… ,xn&#xff08;不妨假设 0x1 ≤ x2 ≤ … ≤ xn&#xff09;&#xff0c;就很容易算出一共有 n(n-1)/2 个距离的值。而比较困难的问题是&#xff0c;在收集…...

深入探索 JavaScript 中的模块对象

引言 在现代 JavaScript 开发中&#xff0c;模块化编程是一项至关重要的技术。它允许开发者将代码拆分成多个独立的模块&#xff0c;每个模块专注于单一功能&#xff0c;从而提高代码的可维护性、可测试性和复用性。而模块对象则是模块化编程中的核心概念之一&#xff0c;它为…...

R1-Searcher:用强化学习解锁大语言模型检索新能力!

R1-Searcher&#xff1a;用强化学习解锁大语言模型检索新能力&#xff01; 大语言模型&#xff08;LLMs&#xff09;发展迅猛&#xff0c;却常因依赖内部知识而在复杂问题上“栽跟头”。今天解读的论文提出R1-Searcher框架&#xff0c;通过强化学习提升LLMs检索能力。它表现超…...

LangChain框架-PromptTemplate 详解

摘要 本文聚焦于 LangChain 框架中PromptTemplate提示词模板模块的深度解析,主要参考langchain_core.prompts源码模块与官方文档。系统梳理 LangChain 对提示词模板的封装逻辑与设计思路,旨在帮助读者构建全面、深入的知识体系,为高效运用LangChain 框架的提示词模板开发应用…...

【Java ee 初阶】文件IO和操作(下)

书接上文 文本操作的方法 String[] list() 返回 File 对象代表的目录下的所有文件名 File[] listFiles() 返回 File 对象代表的目录下的所有文件&#xff0c;以 File 对象表示 此处是针对File对象打印得到的效果&#xff08;调用了File的toString&#xff09; boolean …...