golang云原生项目之:etcd服务注册与发现

news/2024/7/4 7:44:04 标签: golang, 云原生, etcd

服务注册与发现:ETCD

1直接调包

kitex-contrib: 上面有实现的案例,直接cv。下面是具体的理解

2 相关概念

  • EtcdResolver: etcd resolver是一种DNS解析器,用于将域名转换为etcd集群中的具体地址,以便应用程序可以与etcd集群进行通信。etcd是一个分布式键值存储系统,常用于服务发现、配置共享和分布式锁等应用场景。通过使用etcd resolver,应用程序可以更方便地与etcd集群交互

  • endpoints 用于指定集群的地址列表.例如:etcd1.example.com:2379, etcd2.example.com:2379。应用程序将通过这些地址与etcd集群的各个节点进行通信,以读取和更新数据。

3 案例

直接看例子就能大致明白
client:

func main() {
	r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"})
	if err != nil {
		log.Fatal(err)
	}
	client := hello.MustNewClient("Hello", client.WithResolver(r))
	for {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
		resp, err := client.Echo(ctx, &api.Request{Message: "Hello"})
		cancel()
		if err != nil {
			log.Fatal(err)
		}
		log.Println(resp)
		time.Sleep(time.Second)
	}
}

server:

type HelloImpl struct{}

func (h *HelloImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
	resp = &api.Response{
		Message: req.Message,
	}
	return
}

func main() {
	r, err := etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"})
	if err != nil {
		log.Fatal(err)
	}
	server := hello.NewServer(new(HelloImpl), server.WithRegistry(r), server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{
		ServiceName: "Hello",
	}))
	err = server.Run()
	if err != nil {
		log.Fatal(err)
	}
}

4 实际项目实现

4.1 client

  1. handler层接受到app发来的参数如:token、latest_time,根据文档规范封装为一个向后端发起的请求:FeedRequest.
  2. rpc远程调用server的Feed接口,返回目标结果
    在这里插入图片描述
    • rpc调用的Feed实际上先调用了kitex自动生成的client,通过client与server通信,实现调用server的接口。
    • kitex自动生成的client需要在使用前初始化,比如进行服务与发现
      具体来说:client又需要注册中心的resolver,拿到resolver的办法就 etcd.NewEtcdResolver([]string{etcdAddr}),传入endpoint就可以直接拿到reslover
      下面是初始化client的例子
// InitVideo
// 在构建client和server通信之前,先关注连通性
func InitVideo(viperConfig *viper.ConfigViper) {
	etcdAddr := fmt.Sprintf("%s:%d", viperConfig.Viper.GetString("etcd.host"), viperConfig.Viper.GetString("etcd.port"))
	resolver, err2 := etcd.NewEtcdResolver([]string{etcdAddr})
	if err2 != nil {
		log.Fatal(err2)
	}
	serverName := viperConfig.Viper.GetString("server.name") //指定客户端所连接的服务的名称
	newClient, err := videoservice.NewClient(
		serverName,
		//client.WithMiddleware(middleware.CommonMiddleware),
		//client.WithInstanceMW(middleware.ClientMiddleware), //实例级别的中间件。这个中间件可能会对客户端的每个请求进行预处理或后处理
		client.WithMuxConnection(1),                        // mux
		client.WithRPCTimeout(300*time.Second),             // rpc timeout
		client.WithConnectTimeout(300000*time.Millisecond), // conn timeout
		client.WithFailureRetry(retry.NewFailurePolicy()),  // retry
		client.WithSuite(tracing.NewClientSuite()),         // tracer 添加了一个追踪器,用于跟踪客户端的请求和响应
		client.WithResolver(resolver),                      // resolver
		// Please keep the same as provider.WithServiceName
		client.WithClientBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serverName}),
	)
	if err != nil {
		// TODO 思考应该直接panic吗
		log.Fatal(err)
	}
	videoClient = newClient
}

4.2 server

  1. 在一个server运行的时候,main是入口,所以需要在main中将自己的服务注册到etcd
    先通过viper的init方法搜索到对于的配置文件,加载到对象config中:
var (
	config      = viper.Init("video")
	serviceName = config.Viper.GetString("server.name")
	serviceAddr = fmt.Sprintf("%s:%d", config.Viper.GetString("server.host"), config.Viper.GetInt("server.port"))
	etcdAddr    = fmt.Sprintf("%s:%d", config.Viper.GetString("etcd.host"), config.Viper.GetInt("etcd.port"))
	signingKey  = config.Viper.GetString("JWT.signingKey")
	logger      = zap.InitLogger()
)
  1. 服务注册
    之前服务发现是NewEtcdResolver,现在注册是:r, err := etcd.NewEtcdRegistry([]string{etcdAddr}),将得到一个Registry类型的对象
    在这里插入图片描述
  2. 调kitex自动生成的service的NewServer方法,注意使用上面拿到的Registry对象在这里插入图片描述
  3. 上面的启动main方法已经将VideoServiceImpl注册好了,现在可以在脚手架中写具体的各个Impl的接口实现。
    在这里插入图片描述

http://www.niftyadmin.cn/n/4952121.html

相关文章

【Golang系统开发】搜索引擎(3) 压缩倒排索引表

写在前面 假设我们的数据集中有 800000 篇文章,每篇文章有 200 词条,每个词条有6个字符,倒排记录数目是 1 亿。那么如果我们倒排索引表中单单记录文档id,不记录文档内的频率和偏移信息。 那么 文档id 的长度就必须是 l o g 2 8…

如何使用PHP Smarty模板进行AJAX交互?

首先,我们要明白,AJAX是一种在无需刷新整个页面的情况下,与服务器进行通信的技术。这对于改善用户体验来说,是个大宝贝。而PHP Smarty模板则是PHP的一种模板引擎,它使得设计和开发人员能够更好地分离逻辑和显示。 现在…

基于GUI的卷积神经网络和长短期神经网络的语音识别系统,卷积神经网的原理,长短期神经网络的原理

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 长短期神经网络的原理 基于GUI的卷积神经网络和长短期神经网络的语音识别系统 代码下载链接:基于MATLABGUI编程的卷积神经网络和长短期…

MySQL数据类型篇

数值类型 类型有符号(SIGNED)取值范围无符号(UNSIGNED)取值范围大小描述TINYINT(-128,127)(0,255)1byte小整数值SMALLINT(-32768,32767)(0,65535)2bytes大整数值INT/INTEGER(-2147483648,2147483647)(0,429…

使用pnpm workspace管理Monorepo架构

在开发项目的过程中,我们需要在一个仓库中管理多个项目,每个项目有独立的依赖、脚手架,这种形式的项目结构我们称之为Monorepo,pnpm workspace就是管理这类项目的方案之一。 一、pnpm简介 1、pnpm概述 pnpm代表performance npm…

【GaussDB】 SQL 篇

建表语句 表的分类 普通的建表语句 复制表内容 只复制表结构 create table 新表名(like 源表名 including all); 如果希望注释被复制的话要指定including comments 复制索引、主键约束和唯一约束,那么需要指定including indexes including constraints &#xf…

推荐一些国内大数据专业较好的学校

随着国家数字化转型,大数据领域对人才的需求越来越多,为了顺应时代,数据科学与大数据技术这个专业于2016年首次开设。北京大学、对外经济贸易大学和中南大学3所高校首批获批开设“数据科学与大数据技术”专业。随后第二年又有32所高校获批“数…

[Python]pytorch与C交互

文章目录 C库ctypes基础数据类型参数与返回值类型数组指针结构体类型回调函数工具函数 示例 ctypes是Python的外部函数,提供了与C兼容的类型,并允许调用DLL库中的函数。 C库 要使函数能被Python调用,需要编译为动态库: # -fPIC…