go-kratos 学习笔记(7) 服务发现服务间通信grpc调用

服务发现

Registry 接口分为两个,Registrar 为实例注册和反注册,Discovery 为服务实例列表获取

创建一个 Discoverer

服务间的通信使用的grpc,放到data层,实现的是从uses服务调用orders服务

app/users/internal/data.go 加入 NewDiscovery和 NewOrderServiceClient,需要把新加的2个方法加入到 ProviderSet

需要把新生成的orderClient注入到Data里面 orderClient orders.OrderClient

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"
	"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)

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

// NewData .

func NewData(c *conf.Data, logger log.Logger, client orders.OrderClient) (*Data, func(), error) {
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
	}
	db, err := gorm.Open(mysql.Open(c.Database.Source), &gorm.Config{})
	if err != nil {
		log.Fatalf("failed to connect database: %v", err)
		panic(err)
	}
	return &Data{
		db:          db,
		log:         log.NewHelper(logger),
		orderClient: client,
	}, 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
}

在users下执行 wire

以ListUser方法为例子进行调用

app/users/internal/user.go

package data

import (
	"context"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
	"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 results []dal.UserMo
	res := r.data.db.Find(&results)
	if res.Error != nil {
		return nil, res.Error
	}

	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
}

从新生成一下代码 buf generate

如果服务是分开部署的,需要拿到对方的存根 proto 执行 kratos proto client xxx.proto生成client

分别启动users和orders 服务是都是注册成功的,由于注册的是http和grpc所有后面拼接的有http和grpc,调用的时候需要拼接上

postman请求看效果

复制代码
看日志输出 users

再看orders服务的日志输出

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

相关推荐
cuisidong19971 分钟前
5G学习笔记三之物理层、数据链路层、RRC层协议
笔记·学习·5g
乌恩大侠2 分钟前
5G周边知识笔记
笔记·5g
南宫理的日知录8 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
数据与后端架构提升之路1 小时前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
一行11 小时前
电脑蓝屏debug学习
学习·电脑
咔叽布吉1 小时前
【论文阅读笔记】CamoFormer: Masked Separable Attention for Camouflaged Object Detection
论文阅读·笔记·目标检测
johnny2331 小时前
《大模型应用开发极简入门》笔记
笔记·chatgpt
亦枫Leonlew1 小时前
微积分复习笔记 Calculus Volume 1 - 4.7 Applied Optimization Problems
笔记·数学·微积分·1024程序员节
小肥象不是小飞象1 小时前
(六千字心得笔记)零基础C语言入门第八课——函数(上)
c语言·开发语言·笔记·1024程序员节
星LZX1 小时前
WireShark入门学习笔记
笔记·学习·wireshark