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

news2024/11/17 13:21:41
服务发现

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

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

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

相关文章

可见性::

目录 定义: 解决方法: ①使用synchronized实现缓存和内存的同步 修改一: 加入语句: 代码: 修改2: 在代码块中加入: 代码: 执行结果: 原因: ②使用…

数字经济赋能爱疆事业:同疆共创,打造疆品出疆新通道

在数字化浪潮的推动下,新疆吐鲁番地区正迎来一场前所未有的变革。近日,由同疆共创公司承办的“品牌新力量,助农电商直播行,音乐嘉年华吐鲁番活动”在吐鲁番市火热开展,这一创新举措不仅彰显了同疆共创积极履行社会责任…

【redis】一致性hash算法和hash槽

普通hash取模 直接hash(key)%N , N为机器的数量,但不利于集器扩容或者缩容 一致性hash算法和hash槽 一致性hash算法是在redis 分片中使用,hash槽在redis cluster(集群)中使用 Redis一致性hash:Redis一致性hash是为…

AvaloniaUI的学习

相关网站 github:https://github.com/AvaloniaUI/Avalonia 官方中文文档:https://docs.avaloniaui.net/zh-Hans/docs/welcome IDE选择 VS2022VSCodeRider 以上三种我都尝试过,体验Rider最好。VS2022的提示功能不好,VSCode太慢&#xff0c…

Typora笔记上传到CSDN

1.Typora 安装 Typora链接:百度网盘 提取码:b6d1 旧版本是不需要破解的 后来的版本比如1.5.9把放在typora的根目录下就可以了 2.上传到CSDN 步骤 csdn 写文章-使用MD编辑器-导入本地md文件即可 问题 图片没法显示 原因 图片的链接是本地的 当然没法…

PySide(PyQt)使用QPropertyAnimation制作动态界面

主脚本: # encoding: utf-8 import os import sysfrom PySide6.QtCore import QPropertyAnimation, QEasingCurvefrom UIS import *# 主画面类 class MainWindow(QMainWindow, animationButton_ui.Ui_MainWindow):def __init__(self):super().__init__()self.setup…

【OpenCV C++20 学习笔记】图片处理基础

OpenCV C20 图片处理基础 VS 2022 C20 标准库导入的问题头文件包含以及命名空间声明main函数读取图片读取检查显式图片写入图片 完整代码bug VS 2022 C20 标准库导入的问题 VS还没有完全兼容C20。C20的import语句不一定能正确导入标准库,所以必须要新建一个头文件专…

基站光伏直流叠光能效管理方案

安科瑞 华楠 基站现状和趋势 5G基站是专门提供5G网络服务的公用移动通信基站。5G基站主要用于提供5G空口协议功能,支持与用户设备、核心网之间的通信。按照逻辑功能划分,5G基站可分为5G基带单元与5G射频单元,二者之间可通过CPRI或eCPRI接口…

Flink 技术与应用(一)

Flink技术与应用(初级篇) 起源 Apache Flink 是一个开源的大数据处理框架,其起源可以追溯到一个名为 Stratosphere 的研究项目,旨在建立下一代大数据分析引擎,2010 年,从 Stratosphere 项目中分化出了 Fl…

基于深度学习算法,支持再学习功能,不断提升系统精准度的智慧地产开源了。

智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。通过计算机视觉和…

OpenCV图像滤波(2)均值平滑处理函数blur()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在OpenCV中,blur()函数用于对图像应用简单的均值模糊(mean blur)。这种模糊效果可以通过将图像中的每个像素替…

【OpenCV C++20 学习笔记】调节图片对比度和亮度(像素变换)

调节图片对比度和亮度(像素变换) 原理像素变换亮度和对比度调整 代码实现更简便的方法结果展示 γ \gamma γ校正及其实操案例线性变换的缺点 γ \gamma γ校正低曝光图片矫正案例代码实现 原理 关于OpenCV的配置和基础用法,请参阅本专栏的其…

项目管理中的常用工件(二):可视化工件

项目管理中的常用工件(二):可视化工件 亲和图(affinity diagram)因果图(cause-and-effect diagram)直方图(histogram)流程图(flowchart)散点图&am…

Golang学习笔记20240725,Go语言基础语法

第一个Go程序 package mainimport "fmt"func main() {fmt.Println("hello world") }运行方式1: go run main.go运行方式2: go build .\hello_go.exe运行方式3:goland右键运行 字符串拼接 使用加号可以对字符串进行…

数据结构初阶 · 二叉搜索树

目录 前言: 二叉搜索树的实现 二叉搜索树的基本结构 增 查 中序遍历 删 前言: 在最初学习二叉树的时候,就提及到过单独用树来存储数据是既不如链表也不如顺序表的,二叉树的用处可以用来排序,比如堆排序,也可以用来搜索数据…

雷军的逆天改命与顺势而为

雷军年度演讲前,朋友李翔提了一个问题:雷军造车是属于顺势而为还是逆势而为?评论互动区有一个总结,很有意思,叫“顺势逆袭”。 大致意思是产业趋势下小米从手机到IOT再切入汽车,是战略的必然,不…

学习Java的日子 Day58 Servlet的生命周期,安全问题,页面跳转,中文乱码问题

Day58 1.Servlet的生命周期 创建&#xff1a;第一次发送给该Servlet请求时 ​ 调用&#xff1a;构造方法、init() 销毁&#xff1a;服务器正常关闭 ​ 调用&#xff1a;destroy() Welcome.html 没有明确写出是什么请求&#xff0c;那就是get请求 <!DOCTYPE html> <ht…

JavaWeb笔记_JSTL标签库JavaEE三层架构案例

一.JSTL标签库 1.1 JSTL概述 JSTL(jsp standard tag library):JSP标准标签库,它是针对EL表达式一个扩展,通过JSTL标签库与EL表达式结合可以完成更强大的功能 JSTL它是一种标签语言,JSTL不是JSP内置标签 JSTL标签库主要包含: ****核心标签 格式化标签 …

7月25日JavaSE学习笔记

线程的生命周期中&#xff0c;等待是主动的&#xff0c;阻塞是被动的 锁对象 创建锁对象&#xff0c;锁对象同一时间只允许一个线程进入 //创建锁对象Lock locknew ReentrantLock(true);//创建可重入锁 可重入锁&#xff1a;在嵌套代码块中&#xff0c;锁对象一样就可以直接…

分享几种电商平台商品数据的批量自动抓取方式

在当今数字化时代&#xff0c;电商平台作为商品交易的重要渠道&#xff0c;其数据对于商家、市场分析师及数据科学家来说具有极高的价值。批量自动抓取电商平台商品数据成为提升业务效率、优化市场策略的重要手段。本文将详细介绍几种主流的电商平台商品数据批量自动抓取方式&a…