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.rhkb.cn/news/331546.html

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

相关文章

java如何获取IP和IP的归属地?

在Java中,获取IP地址通常指的是获取本地机器的IP地址或者通过某种方式(如HTTP请求)获取的远程IP地址。代码案例如下: 而要获取IP的归属地(地理位置信息),则通常需要使用第三方IP地址查询服务,我…

【C++ QT项目实战-03】---- C++ QT系统实现读取JSON文件数据的自动化模式

🎩 欢迎来到技术探索的奇幻世界👨‍💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介:C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &#…

解决在cmd里下载的库,但IDLE还是显示不存在的问题

原因一: 环境变量配置 首先,你需要确认你安装库的时候使用的Python环境是否和IDLE使用的Python环境是同一个。如果cmd中你使用的是系统路径下的Python,而IDLE使用的是另一个路径下的Python,那么你在cmd中下载的库,IDL…

SQLiteOpenHelper数据库帮助器

SQLiteOpenHelper数据库帮助器是Android提供的数据库辅助工具。 1、继承SQLiteOpenHelper类,需要重写onCreate和onUpgrade两个方法 案例:实现增删改查 package com.example.databases_text;import android.app.PictureInPictureParams; import androi…

Echarts图表使用

ECharts是一个用JS实现开源可视化库&#xff0c;它提供了丰富的图表类型和交互能力。使用户可以通过简单的配置生成各种各样的图表。 先安装ECharts图表直接下载echarts.min.js并用<script>标签引入也可以使用源代码版本echarts.js并用<script>标签引入&#xff0…

Go 1.23 Release Notes编写方式改进!

2024.5.22日&#xff0c;Go 1.23 feature冻结&#xff01;Go团队开始Go 1.23rc1的冲刺&#xff0c;截至发文时&#xff0c;Go 1.23 milestone已经完成59%(https://github.com/golang/go/milestone/212)&#xff0c;还有188个open的issue待解决。 Go 1.23有哪些新feature&#x…

民国漫画杂志《时代漫画》第13期.PDF

时代漫画13.PDF: https://url03.ctfile.com/f/1779803-1247458360-14efab?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

简易进程池的实现

什么是进程池&#xff1f; 进程池&#xff08;Process Pool&#xff09;是一种用于管理和复用多个进程的技术或设计模式。在进程池中&#xff0c;一定数量的进程会被预先创建并保持在内存中&#xff0c;以便在需要时立即使用&#xff0c;而不是每次需要进程时都重新创建新的进程…

基于Qt的社团信息管理系统

企鹅2583550535 项目和论文都有 第1章 绪论... 1 1.1 研究背景与意义... 1 1.2 国内外发展现状... 2 1.3 研究内容... 3 第2章 关键技术介绍... 4 2.1 主要开发技术... 4 2.1.1 C. 4 2.1.2 QT框架... 4 2.1.3 MySQL数据库... 5 2.1.4 TCP协议... 6 2.2 其他技术介绍.…

GPIO模拟spi时序点亮数码管

目录 spi.h spi.c main.c 实验效果 spi.h #ifndef __SPI_H__ #define __SPI_H__#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h"//spi初始化 void spi_init(); //spi写入数据 void spi_write(unsigned char data);#endif spi.c #include…

Andoird使用Room实现持久化及使用Room进行增删查改

文章目录 Room概述Room的使用一、在gradle.build中添加依赖库kotlinJava 创建实体类创建抽象Dao层接口创建DataBase层使用创建的查看数据库 总结&#xff1a; 这篇文章会告诉你如何在Android中通过kotlin或者Java来实现数据持久化 Room概述 处理大量结构化数据的应用可极大地受…

深入了解Socket套接字

目录 一、引入&#x1f64c; 1、概念 &#x1f389; 2、分类&#x1f389; Socket 套接字主要针对传输层协议分为流套接字、数据报套接字、原始套接字&#xff08;了解即可&#xff09;三类。 1&#xff09;流套接字&#xff1a;使用传输层TCP协议 2&#xff09;数据报套…

温故而知新-MySQL篇【面试复习】

温故而知新-数据库篇【面试复习】 前言版权推荐温故而知新-Mysql篇Mysql常见面试题Mysql事务Mysql索引Mysql锁Mysql日志Mysql中的Buffer 数据库的三范式是什么MySQL对于LRU的优化InnoDB三大特性自适应哈希索引&#xff08;Adaptive Hash Index&#xff09;插入缓存&#xff08;…

基于51单片机的盆栽自动浇花系统

一.硬件方案 工作原理是湿度传感器将采集到的数据直接传送到ADC0832的IN端作为输入的模拟信号。选用湿度传感器和AD转换&#xff0c;电路内部包含有湿度采集、AD转换、单片机译码显示等功能。单片机需要采集数据时&#xff0c;发出指令启动A/D转换器工作&#xff0c;ADC0832根…

HLS入门

文章目录 一HLS是什么1HLS介绍 二HLS核心技术以及技术局限性1HLS的核心技术2HLS的技术局限性 三HLS的LED流水灯1创建项目工程2代码3仿真 一HLS是什么 1HLS介绍 HLS是一种将高级编程语言&#xff08;如 C、C等&#xff09;描述的算法或逻辑自动转换为 FPGA 可实现的硬件描述语…

计算机网络学习小结_物理层

数据通信基础知识 信道相关概念 单工&#xff0c;半双工&#xff0c;全双工 基带信号&#xff1a;信源发出的信号&#xff0c;如计算机输出的文字和图像都是基带信号。基带信号常包含较多低频成分&#xff0c;有的还有直流成分&#xff0c;有的信道不能传输低频成分和直流成…

数据结构--顺序表

目录 1.顺序表 1.1顺序表的概念及结构 线性表 2、顺序表分类 2.1顺序表和数组的区别 静态顺序表 动态顺序表 3.顺序表的实现 3.1初始化 随后便可对顺序表初始化 3.2插入数据 尾插 头插 在指定位置插入数据 顺序表的查找 头删、尾删及指定位置删除 实现代码&#x…

汽车R155法规中,汽车获取到的VTA证书,E后面的数字表示什么意思?

标签&#xff1a; 汽车R155法规中&#xff0c;汽车获取到的VTA证书&#xff0c;E后面的数字表示什么意思&#xff1f;&#xff1b; 汽车&#xff1b;VTA认证; 有些厂商汽车拿到的VTA证书上面写着E9&#xff0c; 有些厂商汽车拿到的VTA证书上面写着E5&#xff0c;E9与E5有什么差…

primeflex样式库笔记 Display相关的案例

回顾 宽度设置的基本总结 w-full&#xff1a;表示widtdh&#xff1a;100%&#xff1b;占满父容器的宽度。 w-screen&#xff1a;表示占满整个屏幕的宽度。 w-1到w-12&#xff0c;是按百分比划分宽度&#xff0c;数字越大&#xff0c;占据的比例就越大。 w-1rem到w-30rem&…

Vitis HLS 学习笔记--控制驱动任务示例

目录 1. 简介 2. 代码解析 2.1 kernel 代码回顾 2.2 功能分析 2.3 查看综合报告 2.4 查看 Schedule Viewer 2.5 查看 Dataflow Viewer 3. Vitis IDE的关键设置 3.1 加载数据文件 3.2 设置 Flow Target 3.3 配置 fifo 深度 4. 总结 1. 简介 本文对《Vitis HLS 学习…