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

相关推荐
MUTA️几秒前
RT-DETR学习笔记(2)
人工智能·笔记·深度学习·学习·机器学习·计算机视觉
codists22 分钟前
《计算机组成及汇编语言原理》阅读笔记:p82-p85
笔记
ladymorgana26 分钟前
【运维笔记】windows 11 中提示:无法成功完成操作,因为文件包含病毒或潜在的垃圾软件。
运维·windows·笔记
炭烤玛卡巴卡26 分钟前
初学elasticsearch
大数据·学习·elasticsearch·搜索引擎
oneouto44 分钟前
selenium学习笔记(一)
笔记·学习·selenium
张铁铁是个小胖子1 小时前
MyBatis学习
java·学习·mybatis
我曾经是个程序员1 小时前
鸿蒙学习记录之http网络请求
服务器·学习·http
m0_748232391 小时前
WebRTC学习二:WebRTC音视频数据采集
学习·音视频·webrtc
虾球xz3 小时前
游戏引擎学习第55天
学习·游戏引擎
oneouto3 小时前
selenium学习笔记(二)
笔记·学习·selenium