go缓存设计 redis 发布订阅

news/2025/12/8 20:28:58/文章来源:https://www.cnblogs.com/majiang/p/19323530

go缓存设计 redis 发布订阅

一般缓存 有内存缓存, 没有就读redis, redis没有就读tidb;如何防止缓存穿透,这里我们用golang.org/x/sync/singleflight解决,还有缓存更新,比如多个节点如何更新,这里借用redis 发布订阅;需要更新redis 就发送一条发布消息, 订阅的所有结点就删除内存缓存

缓存代码如下:

package mainimport ("context""encoding/json""fmt""github.com/patrickmn/go-cache""github.com/redis/go-redis/v9""golang.org/x/sync/singleflight""time"
)var globalCache *cache.Cache
var channelKey = "cache_Channel"
var rdb *redis.Clientfunc init() {globalCache = cache.New(5*time.Minute, 10*time.Minute)rdb = redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "", // no password setDB:       0,  // use default DB
    })ctx := context.Background()if _, err := rdb.Ping(ctx).Result(); err != nil {panic(err)}pubSub := rdb.Subscribe(ctx, channelKey)go func() {ch := pubSub.Channel() // 获取一个 channel,用于接收消息for msg := range ch {  // 循环读取消息if key := msg.Payload; len(key) > 0 {rdb.Del(ctx, key).Err()globalCache.Delete(key)fmt.Println(fmt.Sprintf("redis 订阅%s", key))}}}()}func GetCacheData[T any](ctx context.Context, key string, t T, load func() (T, error)) error {val, ok := globalCache.Get(key)if ok {t, ok = val.(T)if ok {fmt.Println(fmt.Sprintf("内存 读取 %s", key))return nil}}client := rdbvar sg singleflight.Groupval, err, _ := sg.Do(key, func() (interface{}, error) {//读取redisstr, err := client.Get(ctx, key).Result()if err == nil && len(str) > 0 {err = json.Unmarshal([]byte(str), &t)if err == nil {globalCache.Set(key, t, time.Minute*1)}fmt.Println(fmt.Sprintf("redis 读取 %s", key))return t, err}if err != nil && err != redis.Nil {return nil, err}t, err = load()if err != nil {return nil, err}fmt.Println(fmt.Sprintf("db 读取 %s", key))jsonByte, err := json.Marshal(t)if err != nil {return nil, err}//设置redis 缓存err = client.Set(ctx, key, string(jsonByte), time.Minute*5).Err()if err != nil {return t, err}return t, nil})if err != nil {return err}t = val.(T)globalCache.Set(key, t, time.Minute*1)return err
}func RemoveCache(ctx context.Context, key string) error {//通知其他节点err := rdb.Publish(ctx, channelKey, key).Err()if err != nil {return err}fmt.Println(fmt.Sprintf("redis 发布 %s", key))return err
}

这里redis 部分 是否需要方法 singleflight.Group 根据实际情况, 但是tidb部分需要放到里面,使用代码

package mainimport ("context""fmt"
)func main() {ctx := context.Background()key := "firstDemo111"p := new(Person)err := GetCacheData[*Person](ctx, key, p, f)//fmt.Println(fmt.Sprintf("%+v", p))err = GetCacheData[*Person](ctx, key, p, f)//	fmt.Println(fmt.Sprintf("%+v", p))RemoveCache(ctx, key)err = GetCacheData[*Person](ctx, key, p, f)//fmt.Println(fmt.Sprintf("%+v", p))err = GetCacheData[*Person](ctx, key, p, f)ch := make(chan int, 1)val := <-chfmt.Println(val)fmt.Println(err)
}type Person struct {Name stringAge  int
}func f() (*Person, error) {return &Person{Name: "demo", Age: 19}, nil
}

  运行效果 确认,多个节点 redis 订阅 发布可以通信

image

 

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

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

相关文章

npm几个实用命令

现在前端开发基本每天都会用到npm命令,最近在解决安全团队报告的安全风险时,发现了几个npm非常实用的命令,特记录下来...前言 最近接到公司安全团队的项目风险表格,列出了当前前端项目的一些安全风险,大概有190多…

产品研发管理 : 构建世界一流的产品研发管理体系

针对大部分客户分不清R&D 中R( 技术开发) 和D( 产品开发) 的区别,面临着研发周期长,需求不清晰,公司越做越大,却越来越不赚钱,越来越缺少核心竞争能力,研发人员越来越多,越来越难管理等问题。中国的大部分技…

iOS 知识点 - 多线程总结(GCD/Operation/Swift Concurrency/线程安全/线程通信)

前景回顾 简单回顾四个概念:进程 vs 线程进程:是操作系统资源分配的最小单位每个 App 通常就是一个进程,进程之间相互隔离,拥有各自的虚拟内存空间、文件描述符、沙盒目录。线程:是 CPU 任务调度的最小单位每个进…

前端实现页面截图及截图内容包含跨域图片时的处理

项目中遇到需要实现指定位置的截图,采取使用依赖 html2canvas 实现。 参考:https://html2canvas.hertzen.com/ 一、实现步骤: 1、下载依赖或者使用官方js文件链接,本文使用的js链接; 2、代码 style .screen-box {…

2025.12.8

今天练习了前后端的连接一起的增删改查

(最新)2025实测!这11款免费降AI率工具,哪款能救你论文?

(最新)2025实测!这11款免费降AI率工具,哪款能救你论文?一篇AI率高达92%的论文摘要,经过专业工具处理后竟能降至个位数,而某些免费工具却可能把它改得“面目全非”。选择正确的降AI工具,关乎你的论文命运。 凌晨…

LLM应用剖析: 小红书AI图文生成器-红墨

本文介绍了小红书的一键图文生成平台,并提供了系统的基本执行流程及原理。同时分享了本人基于本地部署后,生成的图文效果,眼过千遍不如手过一遍,实践方能出真知。1. 背景花了近一周时间,深入研究了Github近几天比…

openSIS 8.0 SQL注入漏洞技术分析与利用

本文详细分析了openSIS社区版8.0中存在的SQL注入漏洞(CVE-2021-40617),提供了完整的漏洞利用证明和复现步骤,涉及通过ForgotPassUserName.php参数注入的具体攻击向量。漏洞标题: openSIS Community Edition 8.0 - …

【把Linux“聊”明白】进程的概念与状态 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

17.Mybatis之代理对象的执行

1.调用 Mapper 方法时,所有请求都会转发到 MapperProxy.invoke(),这是整个流程的入口: public class MapperProxy<T> implements InvocationHandler, Serializable {private final SqlSession sqlSession;pri…

哥大与某机构共建AI研究中心,五年投资500万美元

文章宣布了某机构与哥伦比亚大学工程学院合作,在纽约创立人工智能技术中心。该中心将获得500万美元的五年期资助,用于支持博士生奖学金、跨学科研究项目以及公开研讨会,旨在推动人工智能技术的前沿创新与应用普及。…

中国电子学会全国机器人技术等级考试(一级)2019年12月 - 详解

中国电子学会全国机器人技术等级考试(一级)2019年12月 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

道1:“知识型英语”和“本能型英语”都要学

两种记忆系统: ……陈述性记忆:事实and概念,存储关于……的知识 ……程序性记忆:技能and习惯,存储如何做的知识 两种英语(都要学): ……知识型英语:知识记忆模式,多静态输入。核心策略:理解加记忆、语法当公…

IDEA源码阅读神器-Diagram专业的工具

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

读书笔记 XILINX ug1137-Zynq UltraScale+ MPSoC Software Developer Guide 软件开发者指南 Chapter7

读书笔记 XILINX ug1137-Zynq UltraScale+ MPSoC Software Developer Guide 软件开发者指南 Chapter7目录前言Chapter 7: System Boot and Configuration 系统引导和配置7.1 Boot Process Overview 引导过程概述7.2 Bo…

2025年苗木批发基地供应商口碑榜:前十强深度解析,丝棉木/金森女贞/青叶复叶槭/红叶李/国槐/白蜡/无刺枸骨球苗木批发基地供应商排行榜单

随着城乡绿化建设标准提升与生态修复项目持续推进,苗木产业作为基础支撑环节,其供应商的综合实力与市场口碑愈发受到行业关注。一个可靠的苗木批发基地,不仅需要具备丰富的产品矩阵,更需在种植规范化、品质稳定性及…

2025 年优质服装批发市场推荐:精准适配需求,解锁高效采批新体验

中国服装协会《2024-2025 中国服装行业发展报告》显示,服装采购商年均采批频次提升 23%,但货源同质化、物流低效、线上线下断层等问题仍制约采批效率。红遍天旗下三大专业市场 ——apM 时代国际、红遍天 CENTRE、Ava…

MySQL 性能实测:Docker 容器 vs 裸机部署,差距到底有多大?

本文通过多组对照实验,深入测试 MySQL 在 Docker 容器和裸机环境下的性能差异,揭示影响性能的真正因素。测试背景 网上关于 "Docker 部署数据库会有性能损耗" 的说法众说纷纭。为了搞清楚真相,我在阿里云…

详细介绍:【二叉搜索树】:程序的“决策树”,排序数据的基石

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

thinkphp6 request /i /s等转换

在ThinkPHP框架中,`$this->request->post(type/s, )`里的`/s`是一个参数过滤和类型转换的标识。 具体含义:- `/s` 表示将获取到的参数转换为字符串类型(string)。 如果不加`/s`,默认情况下ThinkPHP会根据参…