go-zero(十) 數(shù)據(jù)緩存和Redis使用

go zero Redis使用和數(shù)據(jù)緩存

一、創(chuàng)建帶有緩存的model

1.生成代碼

我們還是使用之前的user表,具體形式如下:

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
;

現(xiàn)在我們可以通過goctl來生成一帶有緩存的model:

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

-c 代表使用緩存

生成后我們把原來的model文件替換的掉,現(xiàn)在我們看下生成的代碼:

// 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 多了一個(gè)c cache.CacheConf cache參數(shù)

我們追蹤下代碼:

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 其實(shí)就是 Redis

2. 使用Cache

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

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

接著修改config.go,在結(jié)構(gòu)體中添加 cache:

type Config struct {
    rest.RestConf
    /*
    ....
    */
    // 在結(jié)構(gòu)體中增加cache
    Cache       cache.CacheConf
}

最后在servicecontext.go 中,修改NewUserModel的參數(shù):

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. 測(cè)試

現(xiàn)在我們運(yùn)行項(xiàng)目測(cè)試一下:

我們登錄賬號(hào)后,可以看到redis里面多了一個(gè)信息:

image.png

二、 使用redis

剛剛我們介紹了cache,也知道了cache就是redis,現(xiàn)在來正式介紹下redis.

還是一樣我們首先要配置redis

1. 配置redis

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

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

如果資源比較有限可以把redis 和cache用同一個(gè)配置,如果資源比較富裕可以分開使用。

接著修改config.go,在結(jié)構(gòu)體中添加 redis配置:

type Config struct {
    rest.RestConf
    /*
    ....
    */
    // 在結(jié)構(gòu)體中增加redis配置
    RedisConfig redis.RedisConf
}

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

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

修改服務(wù)端代碼,在登錄實(shí)現(xiàn)token存儲(chǔ)到redis中:

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, "數(shù)據(jù)庫(kù)連接失敗")
    }

    //從配置文件中獲取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錯(cuò)誤")
    }
    //查詢username判斷是否有數(shù)據(jù)
    if user != nil {
        //如果有數(shù)據(jù),密碼是否和數(shù)據(jù)庫(kù)匹配
        if in.Password == user.Password {

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

        } else {
            return nil, errors.New(5, "密碼錯(cuò)誤")
        }
    } else {
        return nil, errors.New(6, "用戶未注冊(cè)")

    }
}

redis 的設(shè)置方法有幾種,具體的可以看代碼,我這里使用的是SetexCtx

3. 運(yùn)行項(xiàng)目測(cè)試

可以看到token 成功的存儲(chǔ)到了redis中


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容