实现服务注册与发现(Zookeeper介绍、安装以及使用)

之前的博文中实现了负载轮询的实现,但是还存在一定的问题,就是上游并不知道下游的服务是否仍然是可用的状态,所以我们就需要借助zookeeper来实现服务的注册与发现

Zookeeper介绍

Apache官网中,zookeeper是这样描述的

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.

大概意思是它是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

Zookeeper的服务注册与发现架构

在这里插入图片描述
在此架构中有三类角色:服务提供者,服务注册中心,服务消费者。

服务提供者

服务提供者作为服务的提供方将自身的服务信息注册到服务注册中心中。

服务注册中心

服务注册中心主要提供所有服务注册信息的中心存储,同时负责将服务注册信息的更新通知实时的Push给服务消费者。

服务消费者

服务消费者在启动时从服务注册中心获取需要的服务注册信息,将服务注册信息缓存在本地

根据本地缓存中的服务注册信息构建服务调用请求,并根据负载均衡策略(随机负载均衡,Round-Robin负载均衡等)来转发请求

监听服务注册信息的变更,如接收到服务注册中心的服务变更通知,则在本地缓存中更新服务的注册信息

对服务提供方的存活进行检测,如果出现服务不可用的服务提供方,将从本地缓存中剔除

服务消费者只在自己初始化以及服务变更时会依赖服务注册中心,在此阶段的单点故障通过Zookeeper集群来进行保障。在整个服务调用过程中,服务消费者不依赖于任何第三方服务

在golang中简单应用zookeeper的api

在应用之前我们需要先熟悉一下zookeeper的存储架构,比如下图是一个树状的一个数据结构,我们在注册/app1的之后就可以往/app1中添加子节点,比如我们添加/p_1到/app1中就等于在/app1服务下注册了一个新的服务器节点p_1。我们在/app1处就可以得到发现它的子节点,也就等于服务发现。在/app1处进行监听就可以监听到p_1服务器是否出现故障
在这里插入图片描述

首先我们需要进行zookeeper的安装,

  1. 在apache官网中下载对应的tar包:
    https://zookeeper.apache.org/releases.html
  2. 然后解压缩,并在conf目录下创建一个zoo.cfg文件
  3. 添加配置
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
  1. 运行 bin/zkServer.sh start

这样子我们就能成功把zookeeper服务器运行起来了

下面我们使用golang中的"github.com/samuel/go-zookeeper/zk"包实现服务的注册以及发现

注册

这段代码的逻辑是每5秒在real_server下注册一个节点


import (
	"fmt"
	"github.com/e421083458/gateway_demo/proxy/zookeeper"
	"time"
)

func main() {
	//首先连接到注册中心
	zkManager := zookeeper.NewZkManager([]string{"127.0.0.1:2181"})
	zkManager.GetConnect()
	defer zkManager.Close()
	i := 0
	for {
		//每5秒在real_server下注册一个节点
		zkManager.RegistServerPath("/real_server", fmt.Sprint(i))
		fmt.Println("Register", i)
		time.Sleep(5 * time.Second)
		i++
	}
}

服务发现


var addr = "127.0.0.1:2002"

func main() {
	//连接zk注册中心
	zkManager := zookeeper.NewZkManager([]string{"127.0.0.1:2181"})
	zkManager.GetConnect()
	defer zkManager.Close()
	//获取/real_server下注册的节点列表
	zlist, err := zkManager.GetServerListByPath("/real_server")
	fmt.Println("server node:")
	fmt.Println(zlist)
	if err != nil {
		log.Println(err)
	}

	//动态监听节点变化
	chanList, chanErr := zkManager.WatchServerListByPath("/real_server")
	go func() {
		//循环检测通道内容变化,当有新的节点添加时,chanList通道会发生变化
		for {
			select {
			case changeErr := <-chanErr:
				fmt.Println("changeErr")
				fmt.Println(changeErr)
			case changedList := <-chanList:
				fmt.Println("watch node changed")
				fmt.Println(changedList)
			}
		}
	}()

	//关闭信号监听
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
}

我们把注册和发现运行起来可以发现如下的结果,zookeeperManager能够注册检测到新节点的注册,并把注册的节点打印出来

服务注册:

2020/07/17 12:11:52 Connected to 127.0.0.1:2181
2020/07/17 12:11:52 authenticated: id=72069522072535060, timeout=5000
2020/07/17 12:11:52 re-submitting `0` credentials after reconnect
Register 0
Register 1
Register 2

服务发现:

server node:
[0]
watch node changed
[0]
2020/07/17 12:11:54 Connected to 127.0.0.1:2181
2020/07/17 12:11:54 authenticated: id=72069522072535061, timeout=5000
2020/07/17 12:11:54 re-submitting `0` credentials after reconnect
ChildrenW Event Path:/real_server, Type:EventNodeChildrenChanged
watch node changed
[0 1]
ChildrenW Event Path:/real_server, Type:EventNodeChildrenChanged
watch node changed
[0 1 2]

这样我们就实现了zookeeper中的服务注册和发现的一个小demo,其实我们还可以监听节点的内容变化,这样子就可以对应我们的服务器配置的变化。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值