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中

相关推荐
fat house cat_35 分钟前
【redis】线程IO模型
java·redis
敖云岚2 小时前
【Redis】分布式锁的介绍与演进之路
数据库·redis·分布式
roman_日积跬步-终至千里3 小时前
【Go语言基础【20】】Go的包与工程
开发语言·后端·golang
让我上个超影吧4 小时前
黑马点评【基于redis实现共享session登录】
java·redis
懒羊羊大王呀7 小时前
Ubuntu20.04中 Redis 的安装和配置
linux·redis
John Song9 小时前
Redis 集群批量删除key报错 CROSSSLOT Keys in request don‘t hash to the same slot
数据库·redis·哈希算法
海奥华211 小时前
go中的接口返回设计思想
开发语言·后端·golang
飞川撸码16 小时前
【LeetCode 热题100】网格路径类 DP 系列题:不同路径 & 最小路径和(力扣62 / 64 )(Go语言版)
算法·leetcode·golang·动态规划
Zfox_18 小时前
Redis:Hash数据类型
服务器·数据库·redis·缓存·微服务·哈希算法