go-kratos 学习笔记(8) redis的使用

news2024/11/11 5:45:39

redis的在项目中的使用是很常见的,前面有了mysql的使用redis的也差不多;也是属于在data层的操作,所以需要新建一个 NewRedisCmd方法

在internal/data/data.go中新增NewRedisCmd 方法,注入到ProviderSet

package data

import (
	"context"
	"github.com/go-kratos/kratos/contrib/registry/nacos/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/registry"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/google/wire"
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"github.com/redis/go-redis/v9"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"time"
	"xgs_kratos/gen/config/users"
	"xgs_kratos/gen/orders"
)

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewDiscovery, CreateRegister, NewOrderServiceClient, NewUserRepo, NewRedisCmd)

// Data .
type Data struct {
	// TODO wrapped database client
	db          *gorm.DB
	log         *log.Helper
	orderClient orders.OrderClient
	redisCli    redis.Cmdable
}

// NewData .
func NewData(c *conf.Data, logger log.Logger, client orders.OrderClient, redisCli redis.Cmdable) (*Data, func(), error) {

	db, err := gorm.Open(mysql.Open(c.Database.Source), &gorm.Config{})
	if err != nil {
		log.Fatalf("failed to connect database: %v", err)
		panic(err)
	}
	d := &Data{
		db:          db,
		log:         log.NewHelper(logger),
		orderClient: client,
		redisCli:    redisCli,
	}
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
	}
	return d, cleanup, nil
}

// NewDiscovery 服务发现
func NewDiscovery(conf *conf.Data) registry.Discovery {
	sc := []constant.ServerConfig{
		{
			IpAddr: conf.Nacos.Addr,
			Port:   conf.Nacos.Port,
		},
	}
	cc := constant.ClientConfig{
		NamespaceId: conf.Nacos.NamespaceId,
		TimeoutMs:   5000,
	}

	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &cc,
			ServerConfigs: sc,
		},
	)

	if err != nil {
		panic(err)
	}

	r := nacos.New(client)
	return r
}

// NewOrderServiceClient orders 服务客户端
func NewOrderServiceClient(r registry.Discovery) orders.OrderClient {
	conn, err := grpc.DialInsecure(
		context.Background(),
		grpc.WithEndpoint("discovery:///orders-xgs.grpc"),
		grpc.WithDiscovery(r),
		grpc.WithTimeout(time.Second*2),
		grpc.WithMiddleware(
			recovery.Recovery(),
		),
	)
	if err != nil {
		panic(err)
	}
	c := orders.NewOrderClient(conn)
	return c
}

// NewRedisCmd redis的链接
func NewRedisCmd(conf *conf.Data) redis.Cmdable {
	client := redis.NewClient(&redis.Options{
		Addr:         conf.Redis.Addr,
		ReadTimeout:  conf.Redis.ReadTimeout.AsDuration(),
		WriteTimeout: conf.Redis.WriteTimeout.AsDuration(),
		DialTimeout:  time.Second * 2,
		PoolSize:     10,
	})
	timeout, cancelFunc := context.WithTimeout(context.Background(), time.Second*2)
	defer cancelFunc()
	err := client.Ping(timeout).Err()
	if err != nil {
		log.Fatalf("redis connect error: %v", err)
	}
	return client
}

执行 wire 生成依赖

在业务层使用 data/user.go 中的ListUser 方法做个缓存

package data

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/redis/go-redis/v9"
	"time"
	"xgs_kratos/app/users/internal/biz"
	"xgs_kratos/app/users/internal/data/dal"
	"xgs_kratos/gen/orders"
	"xgs_kratos/gen/users"
)

//data 层处理数据的存储和读取

type userRepo struct {
	data *Data
	log  *log.Helper
}

// NewUserRepo . r registry.Discovery,
func NewUserRepo(data *Data, logger log.Logger) biz.UserRepo {
	return &userRepo{
		data: data,
		log:  log.NewHelper(logger),
	}
}

// CreateUser 创建用户
func (r *userRepo) CreateUser(ctx context.Context, req *users.CreateUserRequest) (*users.CreateUserReply, error) {
	user := dal.UserMo{
		Age:   req.Age,
		Name:  req.Name,
		Email: req.Email,
	}
	result := r.data.db.Create(&user)
	if result.Error != nil {
		return nil, result.Error
	}
	return &users.CreateUserReply{
		Id: user.Id,
	}, nil
}

func (r *userRepo) ListUser(ctx context.Context, req *users.ListUserRequest) ([]*users.UserData, error) {
	//获取order服务的client
	client := r.data.orderClient
	order, err := client.CreateOrder(ctx, &orders.CreateOrderRequest{
		OrderNo: 1,
	})
	if err != nil {
		return nil, err
	}
	fmt.Println(order)
	var redisKey = "user_list"
	//获取redis的数据
	redisData, err := r.data.redisCli.Get(ctx, redisKey).Result()
	if err == redis.Nil {
		redisData = ""
	} else if err != nil {
		return nil, err
	}

	var results []dal.UserMo
	//缓存没有查询到查询数据库
	if redisData == "" {
		fmt.Println("查询了数据库。。。。。。")
		res := r.data.db.Find(&results)
		if res.Error != nil {
			return nil, res.Error
		}
		//把数据转换成json
		resByte, err := json.Marshal(results)
		if err != nil {
			return nil, err
		}
		//设置redis数据
		err = r.data.redisCli.Set(ctx, redisKey, string(resByte), 30*time.Second).Err()
		if err != nil {
			return nil, err
		}
	} else {
		fmt.Println("查询的缓存。。。。。。")
		//查到之后 把数据转换回去
		err = json.Unmarshal([]byte(redisData), &results)
		if err != nil {
			return nil, err
		}
	}
	var userDatas []*users.UserData
	for _, result := range results {
		userDatas = append(userDatas, &users.UserData{
			Id:    result.Id,
			Name:  result.Name,
			Age:   result.Age,
			Email: result.Email,
		})
	}

	return userDatas, nil
}

 然后启动项目 kratos run 看redis的缓存

项目的代码  码云 https://gitee.com/gebilaoxie/xgs_kratos.git

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

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

相关文章

【Java】类与对象、封装(008)

目录 类与对象 ♦️什么类与对象❓ 🎏类的定义 🎃定义一个类 🎃成员变量 🎃成员方法 🎏对象的创建使用和引用传递 🎃对象的创建 🎃对象的引用 封装 ♦️什么是封装❓ ♦️实现封装 …

太阳伴星2600万年回转周期,或许正是它,导致地球生物周期性灭绝?!

我们知道地球已经有46亿年的寿命了,这相比人类生存的时间是极其漫长的。在地球历史中,恐龙在这里生活了1.6亿年,这是地球上相对独特的存在。当然,在恐龙的一生中,它们绝对是地球的统治者。当时,现在统治地球…

stm32入门-----DMA直接存储器存取(上——理论篇)

目录 前言 DMA 1.简介 2.存储器映像 3.DMA结构 4.数据宽度与对齐 5.DMA工作示例 前言 本期我们就开始学习DMA直接存储器存取,DMA是一个数据装运的小助手,执行数据的搬运处理,减少了CPU的负担,在stm32中担当重要的工作。在前…

《Milvus Cloud向量数据库指南》——不同开源向量数据库的适用数据规模及其技术特点深度剖析

在探讨向量数据库领域时,我们不得不提及多个备受瞩目的开源项目,它们各自以其独特的技术优势和适用场景赢得了广泛的关注。本文将深入剖析Milvus Cloud、Chroma、Weaviate、以及Qdrant这几个开源向量数据库在不同数据规模下的应用表现,以及它们各自的技术特点和优势。 引言…

SS9283403 开发环境搭建(二)

1.序 在前一篇“SS928&3403K开发环境搭建(一)”中已经借助Ebaina搭建好的ubuntu对开发板做了测试,这篇记录从零开始搭建SS928&3403K的开发环境; 2.开发前准备 下载VMware Workstation 16 Pro 16.1.0版本 下载ubuntu18.04…

封装导出功能(export)

业务描述: 通过一个button按钮, 实现导出功能, 导出后文件保存到电脑上 目录 一. file-saver 介绍 二. 项目中应用 1. 安装 file-saver库 2.创建 util / exportExcel.js 3. 页面内引入, 使用 4. 页面反馈 展示 一. file-saver 介绍 file-saver是一个用于在前端导出文件…

基于VueCli自定义创建Vue项目架子

基于VueCli自定义创建Vue项目架子 一、VueCli 自定义创建项目1.1安装脚手架 (已安装)1.2.创建项目1.2.1选项1.2.2手动选择功能(按空格可选中)1.2.3选择vue的版本1.2.4是否使用history模式1.2.5选择css预处理1.2.6选择eslint的风格 (eslint 代…

正点原子imx6ull-mini-Linux驱动LED(新字符设备驱动)(3)

经过前几节实验的实战操作,我们已经掌握了 Linux 字符设备驱动开发的基本步骤,字符 设备驱动开发重点是使用 register_chrdev 函数注册字符设备,当不再使用设备的时候就使用 unregister_chrdev 函数注销字符设备,驱动模块加载成功…

Springboot原理相关

目录 配置优先级 bean的管理 获取bean bean的作用域 第三方bean SpringBoot原理 自动配置 配置优先级 在springboot中优先级application.properties>application.yml>application.yaml 虽然支持多种格式配置文件,但是在项目开发中,推荐统…

[MIT6.5840]MapReduce

MapReduce Lab 地址 https://pdos.csail.mit.edu/6.824/labs/lab-mr.html 论文地址 https://static.googleusercontent.com/media/research.google.com/zh-CN//archive/mapreduce-osdi04.pdf 工作原理 简单来讲,MapReduce是一种分布式框架,可以用来处理…

英伟达最强劲敌Groq一招绝杀GPU,反超GPT-4o mini2倍,AI大佬Karpathy:直接飞升AGI!

Llama 3.1 405B被吐槽太笨重? 英伟达对手AI新星Groq一招绝杀:上LPU直接速度翻倍,直接让Llama 3.1飞升AGI! Meta 最新发布的 Llama 3.1 405B 的开源让AI圈不平静了! 追捧者感慨"GPT-4o的能力已握在手中”,而批评者反驳说,大体量消耗这么多算力,有些结果跑得还不如GP…

【内网】安装wget

先是去RPM Search 下载了wget-1.24.5-2.1.x86_64.rpm这个包,结果安装的时候报一堆错 [rootlocalhost ~]# rpm -ivh wget-1.24.5-2.1.x86_64.rpm warning: wget-1.24.5-2.1.x86_64.rpm: Header V3 RSA/SHA512 Signature, key ID 29b700a4: NOKEY error: Failed dep…

不同WEB下的的ApplicationContext的选择

依赖 ApplicationContext类型选择 默认情况下,spring通过选择的web端的框架来选择使用哪个ApplicationContext子类,默认情况下我们一般使用spring mvc框架,这个时候AC的实现类为 org.springframework.boot.web.servlet.context.AnnotationC…

docker安装mysql8自动备份脚本

引用:https://blog.csdn.net/leovnay/article/details/140585094 # 创建两个卷 docker volume ls docker volume create mysqlData docker volume create mysqlSQL# 运行容器 docker run -d --namemysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORDxxx -e TZAsia/Shangh…

Java小抄|Java中的List与Map转换

文章目录 1 List<User> 转Map<User.id,User>2 基础类型的转换&#xff1a;List < Long> 转 Map<Long,Long> 1 List 转Map<User.id,User> Map<Long, User> userMap userList.stream().collect(Collectors.toMap(User::getId, v -> v, …

自闭症儿童上小学教育方法:个性化关怀,引领全面发展

在教育的征程中&#xff0c;为自闭症儿童提供适合他们的小学教育方法至关重要。这些孩子如同独特的星星&#xff0c;需要我们用个性化的关怀去照亮他们的成长之路&#xff0c;引领他们实现全面发展。 个性化关怀是自闭症儿童小学教育的核心。每个孩子都是独一无二的&#xff0c…

钡铼技术PLC网关:实现PLC数据无缝对接MQTT协议

MQTT 协议概述 MQTT 是用于物联网的标准消息传递协议。它被设计为一种非常轻量级的发布/订阅消息传送&#xff0c;非常适合以较小的代码占用量和网络带宽连接远程设备。 PLC网关是一种专门设计用于连接可编程逻辑控制器&#xff08;PLC&#xff09;与其它网络设备或系统的中间…

元器件基础学习笔记——二极管基础

一、二极管基础 二极管是用半导体材料(硅、硒、锗等)制成的一种电子器件&#xff0c;具有单向导电性&#xff0c;是现代电子技术的基石。它在电子电路中扮演着至关重要的角色&#xff0c;通过与电阻、电容、电感等元器件的合理连接&#xff0c;能够实现整流、检波、限幅、稳压等…

python实现GUI版图片锐化小工具

目录 效果展示代码脚本代码 效果展示 锐化前&#xff1a; 锐化后代码 sharpen_img.py import tkinter as tk from tkinter import filedialog from PIL import Image, ImageTk,ImageFilter import os class ImageViewerApp:def __init__(self, root):self.root rootself.r…

空气净化器CE认证简介

空气净化器中有多种不同的技术和介质&#xff0c;使它能够向用户提供清洁和安全的空气。由于空气净化器本身就和我们的生活息息相关。因此对于产品本身的安全性是消费者首先需要考虑的&#xff0c;另一方面就是其在净化空气上的效率和效果。如今国内的空气净化器随着工艺上的不…