go-zero(十) 数据缓存和Redis使用

go zero Redis使用和数据缓存

一、创建带有缓存的model

1.生成代码

我们还是使用之前的user表,具体形式如下:

sql 复制代码
CREATE TABLE `users` (
	`id` BIGINT NOT NULL AUTO_INCREMENT,
	`username` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
	`password` VARCHAR(255) NOT NULL COLLATE 'utf8_general_ci',
	`created_at` TIMESTAMP NULL DEFAULT (CURRENT_TIMESTAMP),
	PRIMARY KEY (`id`) USING BTREE,
	UNIQUE INDEX `username` (`username`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

现在我们可以通过goctl来生成一带有缓存的model:

bash 复制代码
goctl model mysql datasource -url="root:PXDN93VRKUm8TeE7@tcp(127.0.0.1:33069)/test_zero" -table="users" -dir ./model  -c  

-c 代表使用缓存

生成后我们把原来的model文件替换的掉,现在我们看下生成的代码:

go 复制代码
// NewUsersModel returns a model for the database table.
func NewUsersModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UsersModel {
	return &customUsersModel{
		defaultUsersModel: newUsersModel(conn, c, opts...),
	}
}

NewUsersModel 多了一个c cache.CacheConf cache参数

我们追踪下代码:

go 复制代码
type CacheConf = ClusterConf

接着追踪:

type (
	// A ClusterConf is the config of a redis cluster that used as cache.
	ClusterConf []NodeConf

	// A NodeConf is the config of a redis node that used as cache.
	NodeConf struct {
		redis.RedisConf
		Weight int `json:",default=100"`
	}
)

通过上面两段代码可以看到 cache 其实就是 Redis

2. 使用Cache

先在yaml配置文件中,添加redis的配置信息:

Cache: 
  - Host: "redisxxxxxx.redns.redis-cloud.com:16976"
    Pass: "lb8ZWuQwJENyzRiHUFjNnGJG0fgnKx5y"

接着修改config.go,在结构体中添加 cache:

go 复制代码
type Config struct {
	rest.RestConf
	/*
	....
	*/
	// 在结构体中增加cache
	Cache       cache.CacheConf
}

最后在servicecontext.go 中,修改NewUserModel的参数:

go 复制代码
type ServiceContext struct {
	Config          config.Config
	/*
	....
	*/
	
	UserModel       model.UserModel
	

}

func NewServiceContext(c config.Config) *ServiceContext {
	//mysql := NewMysql(c.MysqlDB.DbSource)
	return &ServiceContext{
		Config:        c,
		/*
		....
		*/
		UserModel:     model.NewUserModel(sqlx.NewMysql(c.MysqlDB.DbSource), c.Cache),
		
	}
}

3. 测试

现在我们运行项目测试一下:

我们登录账号后,可以看到redis里面多了一个信息:

二、 使用redis

刚刚我们介绍了cache,也知道了cache就是redis,现在来正式介绍下redis.

还是一样我们首先要配置redis

1. 配置redis

先在yaml配置文件中,添加redis的配置信息:

RedisConfig:
- Host: "redisxxxxxx.redns.redis-cloud.com:16976"
  Pass: "lb8ZWuQwJENyzRiHUFjNnGJG0fgnKx5y

如果资源比较有限可以把redis 和cache用同一个配置,如果资源比较富裕可以分开使用。

接着修改config.go,在结构体中添加 redis配置:

go 复制代码
type Config struct {
	rest.RestConf
	/*
	....
	*/
	// 在结构体中增加redis配置
	RedisConfig redis.RedisConf
}

最后在servicecontext.go 中,添加redis:

go 复制代码
type ServiceContext struct {
	Config          config.Config
	/*
	....
	*/
	
	Redis           *redis.Redis
	

}

func NewServiceContext(c config.Config) *ServiceContext {
	//mysql := NewMysql(c.MysqlDB.DbSource)
	return &ServiceContext{
		Config:        c,
		/*
		....
		*/
		//使用MustNewRedis 链接redis
		Redis:         redis.MustNewRedis(c.RedisConfig),
	}
}

2. 使用redis 保存token

修改服务端代码,在登录实现token存储到redis中:

go 复制代码
func (l *LoginLogic) Login(in *pb.LoginReq) (*pb.LoginResp, error) {
	// todo: add your logic here and delete this line

	userModel := l.svcCtx.UserModel

	user, err := userModel.FindOneByUsername(l.ctx, in.Username)
	if err != nil && err != model.ErrNotFound {
		return nil, errors.New(0, "数据库连接失败")
	}

	//从配置文件中获取secret 、secret
	secret := l.svcCtx.Config.JwtAuth.AccessSecret
	expire := l.svcCtx.Config.JwtAuth.AccessExpire
	//生成jwt token
	token, err := getJwtToken(secret, time.Now().Unix(), expire, in.Username)
	if err != nil {
		return nil, errors.New(4, "token生成失败")
	}
	
	// 登录成功后将用户信息写入 Redis
	err = l.svcCtx.Redis.SetexCtx(l.ctx, fmt.Sprintf("token:%s", token), in.Username, int(expire))
	if err != nil {
		return nil, errors.New(66, "redis错误")
	}
	//查询username判断是否有数据
	if user != nil {
		//如果有数据,密码是否和数据库匹配
		if in.Password == user.Password {

			return &pb.LoginResp{
				Token: "Bearer " + token, //开头添加Bearer
			}, nil

		} else {
			return nil, errors.New(5, "密码错误")
		}
	} else {
		return nil, errors.New(6, "用户未注册")

	}
}

redis 的设置方法有几种,具体的可以看代码,我这里使用的是SetexCtx

3. 运行项目测试

可以看到token 成功的存储到了redis中

相关推荐
MelonTe5 分钟前
Golang网络模型netpoll源码解析
golang
小小李程序员2 小时前
LRU缓存
java·spring·缓存
蚂蚁在飞-4 小时前
一个高度可扩展的 Golang ORM 库【GORM】
数据库·oracle·golang
hai405874 小时前
Spring Boot整合Redis Stack构建本地向量数据库相似性查询
数据库·spring boot·redis
hummhumm5 小时前
第33章 - Go语言 云原生开发
java·开发语言·后端·python·sql·云原生·golang
凡人的AI工具箱6 小时前
40分钟学 Go 语言高并发:【实战】并发安全的配置管理器(功能扩展)
开发语言·后端·安全·架构·golang
Achou.Wang6 小时前
Redis过期时间和SORT命令的高级用法
数据库·redis·bootstrap
XMYX-07 小时前
Redis 在实际业务中的高效应用
redis
CopyLower7 小时前
深入理解 MyBatis 的缓存机制:一级缓存与二级缓存
spring·缓存·mybatis