go-zero 实战(3)

引入 Redis

在之前的 user 微服务中引入 redis。

1. 修改 user/internal/config/config.go

package configimport ("github.com/zeromicro/go-zero/core/stores/cache""github.com/zeromicro/go-zero/zrpc"
)type Config struct {zrpc.RpcServerConfMysql      MysqlConfigCacheRedis cache.CacheConf // redis config -- 加入这一行代码
}type MysqlConfig struct {DataSource string
}

2. 修改 user/etc/user.yaml 文件

加入 redis的配置

CacheRedis:- Host: 127.0.0.1:6379Pass: thinkerType: node

3. 修改 user/database/sqlx.go 文件

修改这里,是为了在查询数据时候,利用redis做缓存。

import ("github.com/zeromicro/go-zero/core/stores/cache""github.com/zeromicro/go-zero/core/stores/sqlc""github.com/zeromicro/go-zero/core/stores/sqlx"
)// we use go-zero sqlxtype DBConn struct {Conn      sqlx.SqlConn    // mysqlConnCache sqlc.CachedConn // redis
}func Connect(datasource string, conf cache.CacheConf) *DBConn {sqlConn := sqlx.NewMysql(datasource)d := &DBConn{Conn: sqlConn,}if conf != nil {cachedConn := sqlc.NewConn(sqlConn, conf)d.ConnCache = cachedConn}return d
}

4. 修改 /user/internal/svc/servicecontext.go 文件

package svcimport ("user/database""user/internal/config""user/internal/dao""user/internal/repo"
)type ServiceContext struct {Config   config.ConfigUserRepo repo.UserRepo
}func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config:   c,UserRepo: dao.NewUserDao(database.Connect(c.Mysql.DataSource, c.CacheRedis)),  // 增加了 redis的缓冲配置}
}

5. 在 user/internal/repo/user.go 中增加接口

package repoimport ("context""user/internal/model"
)type UserRepo interface {Save(ctx context.Context, user *model.User) errorFindById(ctx context.Context, id int64) (user *model.User, err error)  //新增
}

6. 在 user/internal/dao/user.go 中实现接口

func (d *UserDao) FindById(ctx context.Context, id int64) (user *model.User, err error) {user = &model.User{}querySql := fmt.Sprintf("select * from %s where id = ?", user.TableName())userIdKey := fmt.Sprintf("%s%d", cacheUserIdPrefix, id)err = d.ConnCache.QueryRowCtx(ctx, user, userIdKey,func(ctx context.Context, conn sqlx.SqlConn, v any) error {return conn.QueryRowCtx(ctx, v, querySql, id)})return
}

7. 在 user/logic/userlogic.go 中实现 GetUser rpc

func (l *UserLogic) GetUser(in *user.IdRequest) (*user.UserResponse, error) {// todo: add your logic here and delete this lineid, err := strconv.ParseInt(in.Id, 10, 64)if err != nil {return nil, err}u, err := l.svcCtx.UserRepo.FindById(context.Background(), id)if err != nil {return nil, err}return &user.UserResponse{Id:     in.GetId(),Name:   u.Name,Gender: u.Gender,}, nil
}

User 微服务rpc接口增加缓存完成。

测试

1. 修改 userapi/internal/handler/routes.go 文件

增加如下路由代码

{Method: http.MethodGet,Path: "/user/get/:id",Handler: handler.GetUser,
},

2. 修改 userapi/internal/types/types.go 文件

增加一个 IdRequest 结构体,主要是为了处理上一步中的请求

type IdRequest struct {Id string `json:"name" path:"id"`
}

3. 修改 userapi/internal/handler/userhandler.go 文件,实现GetUser接口

文件中增加如下代码:

func (u *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {var req types.IdRequestif err := httpx.ParsePath(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)return}l := logic.NewUserLogic(r.Context(), u.svcCtx)resp, err := l.GetUser(&req)if err != nil {httpx.ErrorCtx(r.Context(), w, err)} else {httpx.OkJsonCtx(r.Context(), w, resp)}
}

4. 修改 userapi/internal/logic/userapilogic.go 文件

文件中增加 GetUser 方法

func (l *UserLogic) GetUser(t *types.IdRequest) (resp *types.Response, err error) {userResponse, err := l.svcCtx.UserRpc.GetUser(context.Background(), &user.IdRequest{Id: t.Id,})if err != nil {return nil, err}resp = &types.Response{Message: "success",Data:    userResponse,}return
}

该方法主要调用了 user微服务的 RPC GetUser接口 服务

5. 启动微服务开始测试

  1. 启动 user 服务
  2. 启动 user api 服务
  3. 测试截图
    在这里插入图片描述
    到此,引入 redis 缓存成功。

go-zero 中的 JWT 使用

jwt 在目前登录、鉴权等场景中引用非常广泛
jwt 是加密的字符串,需要一个密钥,并且可以通过设置过期时间来使 jwt 生成的 token 失效。

由于我们的 userapi 微服务是对外提供接口的,因此,我们在 userapi 中使用 jwt。

1. 修改 userapi/internal/config/config.go 文件

添加 Auth 结构体

package configimport ("github.com/zeromicro/go-zero/rest""github.com/zeromicro/go-zero/zrpc"
)type Config struct {rest.RestConfUserRpc zrpc.RpcClientConfAuth    struct {AccessSecret stringAccessExpire int64}
}

2. 修改 userapi/etc/userapi-api.yaml 文件

在文件中,增加如下配置。

Auth:AccessSecret: "sdskewie@129120$%120&*!"AccessExpire: 604800

3. 修改 userapi/internal/handler/routers.go 文件

func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {handler := NewUserHandler(serverCtx)server.AddRoutes([]rest.Route{{Method:  http.MethodPost,Path:    "/Register",Handler: handler.Register,},{Method:  http.MethodPost,Path:    "/Login",Handler: handler.Login,},},)server.AddRoutes([]rest.Route{{Method: http.MethodGet,Path: "/user/get/:id",Handler: handler.GetUser,},},rest.WithJwt(serverCtx.Config.Auth.AccessSecret),   // need jwt)
}

需要 jwt 认证的接口,就需要 rest.WithJwt(serverCtx.Config.Auth.AccessSecret), 这行go代码 。

4. 修改 userapi/internal/handler/userhandler.go 文件 ,实现 Login 接口

在该 文件 中,添加 Login 方法

func (u *UserHandler) Login(w http.ResponseWriter, r *http.Request) {var req types.LoginRequestif err := httpx.ParseJsonBody(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)return}l := logic.NewUserLogic(r.Context(), u.svcCtx)resp, err := l.Login(&req)if err != nil {httpx.ErrorCtx(r.Context(), w, err)} else {httpx.OkJsonCtx(r.Context(), w, resp)}
}

5. 修改 userapi/internal/login/userapilogin.go 文件

在该文件中,添加 login 方法,登录成功后生成 jwt

func (l *UserLogic) getToken(secretKey string, iat, seconds int64, userId int) (string, error) {claims := make(jwt.MapClaims)claims["exp"] = iat + secondsclaims["iat"] = iatclaims["userId"] = userIdtoken := jwt.New(jwt.SigningMethodES256)token.Claims = claimsreturn token.SignedString([]byte(secretKey))
}func (l *UserLogic) Login(t *types.LoginRequest) (string, error) {userId := 100auth := l.svcCtx.Config.Authreturn l.getToken(auth.AccessSecret, time.Now().Unix(), auth.AccessExpire, userId)
}

6. 启动 useapi微服务 测试

  1. 加入 jwt 后,再次测试 user/get/1接口,返回401
    在这里插入图片描述
  2. 先登录,拿到 jwt
    在这里插入图片描述
  3. 使用 jwt 访问 user/get/1 接口
    在这里插入图片描述
    jwt 测试成功。

github位置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/17011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Overall Accuracy(OA)、Average Accuracy(AAcc)计算公式

以二分类为例:1.总体精度(Overall Accuracy, OA):样本中正确分类的总数除以样本总数。 OA(TPTN)/(TPFNFPTN)2.平均精度(Average Accuracy, AA):每一类别中预测正确的数目除以该类总数,记为该类的精度,最后求每类精度的…

2022全国大学生数学建模竞赛ABC题(论文+代码)

文章目录 (1)2022A波浪能最大输出功率(2)2022B无人机定位(3)2022C古代玻璃制品成分分析(4)论文和代码链接 (1)2022A波浪能最大输出功率 (2&#x…

su模型转3d模型不够平滑怎么办?---模大狮

当将SU模型转换为3D模型时,可能会遇到模型不够平滑的情况,这会影响到最终的渲染效果和视觉体验。本文将探讨在此情况下应该如何解决,帮助读者更好地处理这一常见的问题。 一、检查SU模型细分程度 首先要检查的是原始的SU模型的细分程度。在S…

XSKY CTO 在英特尔存储技术峰会的演讲:LLM 存储,架构至关重要

5 月 17 日,英特尔存储技术峰会在北京顺利举办。作为英特尔长期的合作伙伴,星辰天合受邀参加了此次峰会。星辰天合 CTO 王豪迈作为特邀嘉宾之一,作了主题为《LLM 存储:架构至关重要》的演讲,分享了大语言模型&#xff…

2024年中国金融行业网络安全案例集

随着科技的飞速发展,金融行业与信息技术的融合日益加深,网络安全已成为金融行业发展的生命线。金融行业作为国家经济的核心支柱,正在面临着日益复杂严峻的网络安全挑战。因此,深入研究和探讨金融行业的网络安全问题,不仅关乎金融行业的稳健运…

MIPI竖屏解决方案,普立晶POL8901升级POL8903 两PORT LVDS桥接到MIPI,加旋转

POL8903描述: 系统: •采用高性能MIPS 32位CPU内核; •高性能DSP内核图像处理单元; •16 KB指令Cache;16 KB数据Cache; •96 KB SRAM;内置DDR 3控制器; LVDS输入: …

Python代码:十七、生成列表

1、题目 描述: 一串连续的数据用什么记录最合适,牛牛认为在Python中非列表(list)莫属了。现输入牛牛朋友们的名字,请使用list函数与split函数将它们封装成列表,再整个输出列表。 输入描述: …

取代或转型?人工智能对软件测试的影响(内附工具推荐)

在当今快速发展的数字环境中,从移动App到基于Web的平台,软件已成为我们日常生活和工作不可或缺的一部分。然而,随着软件系统变得越来越复杂,如何确保其质量和可靠性已成为开发人员和测试人员所面临的一大重要挑战。 这就是软件测…

Autoware 软件功能(二)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务,并且需要GPU资源,可以考虑使用Compshare的GPU算力云平台。他们提供高性价比的4090 GPU,按时收费每卡2.6元,月卡只需要1.7元每小时,并附带200G…

UE5 使用外置摄像头进行拍照并保存到本地

连接外置摄像头功能:https://docs.unrealengine.com/4.27/zh-CN/WorkingWithMedia/IntegratingMedia/MediaFramework/HowTo/UsingWebCams/ 核心功能:UE4 相机拍照功能(图片保存)_ue 移动端保存图片-CSDN博客 思路是: …

万博智云×华为云 | HyperBDR云容灾上架,开启联营联运新篇章

日前,万博智云HyperBDR云容灾正式入驻华为云云商店,成为华为云基础软件领域联营联运合作伙伴。通过联营联运,双方将进一步加深在产品、解决方案、渠道拓展等多方面的强强联合,为企业提供更加安全、高效的数据保护解决方案&#xf…

重量and体积,不要在傻傻的花冤枉钱寄快递了!

寄快递时有没有遇到过明明不重却被按体积收费的情况?别急,今天就来给大家揭秘快递收费的奥秘! 实际重量和体积重量! 首先,我们要明白两个概念:实际重量和体积重量。实际重量就是你看到的物品重量&#xf…

angr使用学习(持续更新)

首先我是直接在kali中安装的,也是边练边学的。 嗯,要在纯净python环境,所以是在 virtualenv 虚拟环境里,也不是特别会用这个,按照教程一步步做的 source venv/bin/activate 进入了对应环境 退出是 deactivate en,ipy…

DataGrip软件执行已将创建好的sql文件步骤

一、在需要导入sql文件上右击找到SQLScript ,然后点击 Run SQL Script 二、找到sql文件,点击OK就可以了

Day01-01-git

Day01-01-git Content List0. 运维发展过程1. ci-cd-co基础1.1 软件的生命周期1)软件的声明周期:软件从0-->1-->0过程2)ci/cd3)Devops4) 小结 1.2 什么是环境1.3 什么是代码部署1.4 代码发布方式 3. DevSecOpt之Git极速入门…

Unity UGUI实现无限滚动列表

Demo链接​​​https://download.csdn.net/download/qq_41973169/89364284http://Unity UGUI无限滚动列表 在游戏开发中,列表视图是一个常见的UI组件。实现一个高效的列表视图尤其重要,尤其是在需要展示大量数据时。本文将介绍如何在Unity中实现一个高效…

手动操作很麻烦?试试这个自动加好友神器吧!

你是不是也觉得手动逐一输入号码或是微信号,再搜索添加很麻烦?试试这个自动加好友神器——个微管理系统,帮助你省去繁琐的手工操作,节省时间和精力。 首先,在系统上登录微信号,无论你有多少个微信号&#…

2024年上半年软件设计师试题及答案(回忆版)--选择题

基础知识选择题 基础知识选择题 1,2,3][4,5,6][1,2,3,4,5,6] (总:1分) (注意:括号内的是截止当前题目总分) vlan不能隔绝内外网 (2分) 链路层使用交换机,…

智慧树下做游戏

游戏开发工程师致力于游戏总体设计 ,负责游戏开发工具和运营维护工具的设计与开发 ,并配合主程序完成游戏架构及各大功能的设计、开发、调试和其他技术支持 就业方向: 一般有客户端游戏开发和服务器游戏开发 客户端开发: 主要负…

光伏开发是用什么工具提高效率?

随着全球对可再生能源的日益重视,光伏产业作为其中的佼佼者,已经取得了长足的发展。然而,如何提高光伏开发的效率,降低成本,成为了业内关注的焦点。本文将探讨光伏开发过程中所使用的工具,以及这些工具如何…