Redis 在Go项目中的集成和统一管理

本节我们在项目中安装和集成 go-redis,让项目能访问Redis,后面实战项目中的用户认证体系会依赖Redis来实现,像Token、Session这些都是在Redis中存储的。

本节大纲如下:‍‍

ecceaada2547bd89e1f470e7e67b3e20.png

Redis的使用场景有不少,不过有一点需要提醒的是别把Redis当数据库用哦。

这里分享一篇 Redis应用场景汇总,里面罗列了十几个场景,大家有兴趣的可以看一下。

go-redis 的安装和配置

在我们的Go项目里访问Redis使用的是 go-redis 这个包,之前也见过一些项目使用redigo 来访问Redis,不过redigo已经停止维护了,所以就不考虑使用它了。

安装 go-redis 使用以下命令

go get github.com/redis/go-redis/v9

安装过程中会向项目依赖中添加下面这些包,在gomod 文件中也会看到它们的身影。

22b1f1abf0d9b87270a11aee9371dde6.png 依赖下载完成后,我们先不着急去初始化它,还是先把相关的配置先在配置文件里写好。在 applicaiton.dev.yaml 增加Redis相关配置。
redis: # 记得更改成自己的连接配置
  addr: 127.0.0.1:31379
  password: 123456
  pool_size: 10
  db: 0

其他两个环境的配置文件建议也先加上,避免配置文件之间结构和字段相差太多,等有测试和生产环境后再把配置调整过去即可。

配置添加完后,我们在 config.go 中增加 Redis 这些配置字段的对应的类型定义

var (
 ...
 Redis    *redisConfig
)

// Redis 配置
type redisConfig struct {
 Addr     string `mapstructure:"addr"`
 Password string `mapstructure:"password"`
 PoolSize int    `mapstructure:"pool_size"`
 DB       int    `mapstructure:"db"`
}

同时也在 bootstrap.go 中把config文件中的redis配置字段映射到 redisConfig 类型的变量 config.Redis

func init() {
 env := os.Getenv("ENV")
 vp := viper.New()
    ...
    
 vp.UnmarshalKey("redis", &Redis)
}

配置做好后,接下来我们在 dal/cache 目录中新建redisinit.go 文件,在其中对go-redis客户端进行初始化

var redisClient *redis.Client

func Redis() *redis.Client {
 return redisClient
}

func init() {
 redisClient = redis.NewClient(&redis.Options{
  Addr:         config.Redis.Addr,
  Password:     config.Redis.Password,
  DB:           config.Redis.DB,
  PoolSize:     config.Redis.PoolSize,
  DialTimeout:  10 * time.Second,
  ReadTimeout:  30 * time.Second,
  WriteTimeout: 30 * time.Second,
  PoolTimeout:  30 * time.Second,
 })
 
 if err :=redisClient.Ping(context.Background()).Err(); err != nil {
  // 连接不上redis 让项目停止启动
  panic(err)
 }}

跟初始化GORM时一样,如果你不想用Go的init机制,这里可以把这个初始化方法修改名成InitRedis,到main函数中去调用它来手动完成初始化。

Redis Key 的管理

我们在使用Redis的时候,最好把Key 放在项目里统一的地方进行管理,同时在命名时给Key加上包含业务、项目、模块信息的前缀名,通过签证在查问题的时候我们最起码能快速定位到缓存是哪个项目写进去的。

我在平时维护项目中被 Redis 搞的头大的大部分情况是,很多旧代码在A项目里缓存了个什么数据,然后到下游的B项目再去读这个数据,根据缓存里数据的状态执行不同的逻辑分支。

有的时候监控系统报告B项目出了Bug,查问题看到从Redis里读取到的数据跟预想的不一样,一般人都会先在B项目中Debug,看下缓存设置的程序是不是有问题,但是针对这种情况把整个B项目搜遍也没发现缓存是从哪里存进去的。 

所以 Redis Key 的命名不能太随意,最好包含设置缓存的项目名、所属业务等能确定缓存来源的信息。

我们在项目的 common/enum 目录中新增rediskey.go 在其中对Redis 缓存的 Key 进行统一管理

/ Redis Key的格式为:
//   项目名:模块名:键名

const (
 REDIS_KEY_DEMO_ORDER_DETAIL = "GOMALL:DEMO:ORDER_DETAIL_%s"
)

这里先定义一个测试用的Redis缓存的键名。

  • GOMALL:DEMO:ORDER_DETAIL_%s

    • Key的格式为 项目名:模块名:键名,你的公司大的话还可以在最前面加一个业务名,免得项目名重复了。

    • 项目名:GOMALL

    • 模块名:DEMO (因为是演示,正常情况下是ORDER、USER 这种模块名)

    • 键名:ORDER_DETAIL_%s

在使用到这个 Redis 缓存的方法中可以来拿业务标识(比如订单号) 拼装出完整的Redis Key

redisKey := fmt.Sprintf(enum.REDIS_KEY_DEMO_ORDER_DETAIL, demoOrder.OrderNo)

Redis怎么做日志链路追踪

和在项目中集成ORM使用数据库时一样,除了关注常规的功能外,我们还要关注组件集成进项目后的可观测性。最基础的保障观测性的方式是组件日志整合到应用日志,并且通过traceId、reqeustId等方式讲它们归因到对应的请求上。

关于这部分日志整合和链路追踪的内容,请扫码订阅专栏后阅读完整版。

ece62f8af37a1160fe08186e56606af0.png

专栏配套的项目有完整的实现代码,订阅后加入项目访问 https://github.com/go-study-lab/go-mall/compare/c8...c9 能看本章节的详细代码。

0cedebcaf9e01a7a6133a18e3ac8521a.png

专栏分为五大部分,主要内容架构如下(已更新32节)

6677953ee102afa0eb0e9fddfadc05c9.png

  • 第一部分介绍让框架变得好用的诸多实战技巧,比如通过自定义日志门面让项目日志更简单易用、支持自动记录请求的追踪信息和程序位置信息、通过自定义Error在实现Go error接口的同时支持给给错误添加错误链,方便追溯错误源头。

  • 第二部分:讲解项目分层架构的设计和划分业务模块的方法和标准,让你以后无论遇到什么项目都能按这套标准自己划分出模块和逻辑分层。后面几个部分均是该部分所讲内容的实践。

  • 第三部分:设计实现一个套支持多平台登录,Token泄露检测、同平台多设备登录互踢功能的用户认证体系,这套用户认证体系既可以在你未来开发产品时直接应用

  • 第四部分:商城app C端接口功能的实现,强化分层架构实现的讲解,这里还会讲解用责任链、策略和模版等设计模式去解决订单结算促销、支付方式支付场景等多种多样的实际问题。

  • 第五部分:单元测试、项目Docker镜像、K8s部署和服务保障相关的一些基础内容和注意事项

扫描上方二维码或者访问 https://xiaobot.net/p/golang 即刻订阅


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值