redis的在项目中的使用是很常见的,前面有了mysql的使用redis的也差不多;也是属于在data层的操作,所以需要新建一个 NewRedisCmd方法
在internal/data/data.go中新增NewRedisCmd 方法,注入到ProviderSet
package dataimport ("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 clientdb *gorm.DBlog *log.HelperorderClient orders.OrderClientredisCli 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 dataimport ("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 *Datalog *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服务的clientclient := r.data.orderClientorder, 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}//把数据转换成jsonresByte, 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.UserDatafor _, 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