go-zero 使用 redis 作为 cache 的 2 种姿势
在 go-zero 框架内,如在 rpc 的应用 service 中,其内部已经预置了 redis 的应用,所以我们只需要在配置中加入相关字段即可,另外,在 svcContext 声明 redis client 后即可在具体的业务逻辑处理中应用。
但这里有个问题,如我用的是 go-zero 1.5.0 版本,从源码分析来看,redis 的连接并没用到 连接池,虽然在 go-zero/redis 已经为我们声明了足够的 redis 操作接口,但如果你有 连接池 的需求,还有另外一条路径,自己在应用中声明 连接池,但是具体的操作,也需要自己去写。
下面就从上面说的两个方面分享下 redis 的两种使用姿势吧。
框架内置的 redis
我们假设你已经生成了 rpc 的应用,然后接下来就是这样的一些主要工作:
- 1.config.go 文件定义你的 redis 配置结构体并放入 config 结构体中, 由于
zrpc.RpcServerConf
含有 Redis 的定义,直接跳转下步 - 2.yaml配置文件中,声明你的配置
- 3.在 svcContext 加入 redisClient
- 4.业务逻辑处理中加入 redis 作为缓存
完成以上,你就完成了通过框架内置的 redis 接口的使用。
定义你的 redis 结构体
internal/config/config.go
type Config struct { zrpc.RpcServerConf }
go-zero/zrpc/config.go
// A RpcServerConf is a rpc server config. type RpcServerConf struct { service.ServiceConf ListenOn string Etcd discov.EtcdConf `json:",optional,inherit"` Auth bool `json:",optional"` Redis redis.RedisKeyConf `json:",optional"` // 这里就是预置的字段 StrictControl bool `json:",optional"` // setting 0 means no timeout Timeout int64 `json:",default=2000"` CpuThreshold int64 `json:",default=900,range=[0:1000]"` // grpc health check switch Health bool `json:",default=true"` Middlewares ServerMiddlewaresConf }
go-zero/core/stores/redis/conf.go
type ( // A RedisConf is a redis config. RedisConf struct { Host string Type string `json:",default=node,options=node|cluster"` Pass string `json:",optional"` Tls bool `json:",optional"` } // A RedisKeyConf is a redis config with key. RedisKeyConf struct { RedisConf Key string `json:",optional"` } )
声明配置
结合上面的内容,你只需要在 yaml 文件中注明下面内容:
Redis: Host: xx.xx.xx.xx:6379 Type: node Tls: false
在 svcContext 加入 redisClient
直接看代码
package svc import ( "userrpcv1/internal/config" zeroRds "github.com/zeromicro/go-zero/core/stores/redis" ) type ServiceContext struct { Config config.Config // claim ur redis client in here RedisClient *zeroRds.Redis } func NewServiceContext(c config.Config) *ServiceContext { //conf := c.Redis redisClient := zeroRds.MustNewRedis(conf.Redis) return &ServiceContext{ Config: c, RedisClient: redisClient, } }
业务逻辑应用
你的某个接口业务逻辑处理
//logx.Info("Set Redis cache now") //err := l.svcCtx.RedisClient.Setex(fmt.Sprintf("Sum:%d:%d", in.A, in.B), fmt.Sprintf("Result:%d time:%v", sum, time.Now().Format(time.RFC3339)), ttl) //if err != nil { // logx.Errorf("Rpc A9Sum set cache error: %v", err) //}
到这里你就成功了,直接拿去用吧。
通过自定义 redis 连接池
这里与上面有些不同,我们会自定义 redis 的结构体,自定义连接池的配置,自定义 client ,以及对应的一些操作,步骤如下:
- 自定义 redis 配置结构体
- yaml文件中声明配置信息
- 编写连接池等的初始化
- 编写连接池的接口
- 业务逻辑处理中使用连接池
自定义 redis 配置结构体
依然还是你的 config.py 中加入以下:
package config import "github.com/zeromicro/go-zero/rest" type Config struct { rest.RestConf CacheConf CacheConf } type CacheConf struct { Password string `json:",optional"` Host string `json:",optional"` Port int64 `json:",optional"` DBName int `json:",optional"` MaxIdle int `json:",optional"` MaxActive int `json:",optional"` IdleTimeout int64 `json:",optional"` }
yaml文件中声明配置信息
Name: limit Host: 0.0.0.0 Port: 8888 MaxConns: 100000 CacheConf: Password: "" Host: 172.30.3.57 Port: 6379 DBName: 15 MaxIdle: 2 MaxActive: 5 IdleTimeout: 1000000000
编写连接池等的初始化
package redis import ( "fmt" "math" "time" "demo24/micro_svc/zero-limit/internal/config" "github.com/gomodule/redigo/redis" "github.com/zeromicro/go-zero/core/logx" ) var ( pool *redis.Pool client redis.Conn ) func InitRedis(conf config.CacheConf) { pool = &redis.Pool{ MaxActive: conf.MaxActive, MaxIdle: conf.MaxIdle, IdleTimeout: time.Duration(conf.IdleTimeout), Dial: func() (redis.Conn, error) { addr := fmt.Sprintf("%s:%s", conf.Host, conf.Port) conn, err := redis.Dial("tcp", addr, redis.DialDatabase(conf.DBName)) if err != nil { logx.Errorf("Create redis pool conn failed, err: %v", err) return nil, err } return conn, nil }, } client = pool.Get() _, err := redis.String(client.Do("ping")) if err != nil { logx.Errorf("redis conn pool init failed, err: %v.", err) } }
编写连接池的接口
func GetRDB() redis.Conn { if pool == nil { logx.Errorf("get redis instance failed, err: pool is nil.") return nil } return pool.Get() } type Cache struct { client redis.Conn } func NewCache() *Cache { return &Cache{ client: GetRDB(), } } func (cache *Cache) Set(key string, value interface{}, nx int) { if nx == 0 { nx = math.MaxInt32 } _, err := cache.client.Do("SET", key, value, "NX", nx) if err != nil { logx.Errorf("set key failed, err: %v", err) } } func (cache *Cache) Get(key string) (val interface{}, err error) { value, err := cache.client.Do("GET", key) if err != nil { logx.Errorf("get cache err, err: %v", err) return nil, err } return value, nil } // TODO, u can implement ur cache operations
业务逻辑处理中使用连接池
... // redis pool //cache := redis.NewCache() //_, err = cache.Get(fmt.Sprintf("Sum:%d:%d", in.A, in.B)) //if err != nil { // logx.Errorf("Rpc A9Sum get cache error: %v", err) //} ...
通过以上流程,你可以实现这两种 go-zero 的使用 redis 作为缓存的方法,希望对你有用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!