博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
微服务中Zookeeper的应用及原理
阅读量:2198 次
发布时间:2019-05-02

本文共 3017 字,大约阅读时间需要 10 分钟。

了解微服务的小伙伴都应该知道,是一个分布式的,开源的分布式应用程序协调服务。

现在比较流行的微服务框架Dubbo、Spring Cloud都可以使用作为服务发现与组册中心。但是,为什么就能实现服务发现与组册呢?

的特性

我们先来了解一下的特性吧,因为它的特性决定了它的使用场景。

1.树状目录结构

如上图,是一个树状的文件目录结构,有点像应用系统中的文件系统的概念。每个子目录(如App)被称为znode,我们可以对每个znode进行增删改查。

2.持久节点(Persistent)

客户端与服务端断开连接后,该节点仍然存在。

3.持久有序节点(Persistent_sequential)

在持久节点基础上,由zookeeper给该节点名称进行有序编号,如0000001,0000002。

4.临时节点(Ephemeral)

客户端与服务端断开连接后,该节点被删除。临时节点下,不存在子节点。

5.临时有序节点(Ephemeral_sequential)

在临时节点基础上,由给该节点名称进行有序编号,如0000001,0000002。

6.节点监听(Wacher)

客户端2注册监听它关心的临时节点SubApp1的变化,当临时节点SubApp1发生变化时(如图中被删除的时候),zookeeper会通知客户端2。

该机制是zookeeper实现分布式协调的重要特性。我们可以通过get,exists,getchildren三种方式对某个节点进行监听。但是该事件只会通知一次。

 

微服务中应用场景

1.分布式锁

分布式锁主要解决不同进程中的资源同步问题。大家可以联想一下单进程中的多线程共享资源的情况,线程需要访问共享资源,首先要获得锁,操作完共享资源后便释放锁。这篇推荐大家阅读。

分布式中,上述的锁就变成了分布式锁了。那这个分布式锁又是如何实现呢?

步骤1: 如图,根据有序临时节点的特性,每个进程对应连接一个有序临时节点(进程1对应节点/znode/00000001,进程2对应节点/znode/00000002…如此类推)。

每个进程监听对应的上一个节点的变化。编号最小的节点对应的进程获得锁,可以操作资源。

步骤2: 当进程1完成业务后,删除对应的子节点/znode/00000001,释放锁。此时,编号最小的锁便获得锁(即/znode/00000002对应进程)。

重复以上步骤,保证了多个进程获取的是同一个锁,且只有一个进程能获得锁,就是分布式锁的实现原理。

 

2.服务注册与发现

2.1 背景

在微服务中,服务提供方把服务注册到中心去如图中的Member服务,但是每个应用可能拆分成多个服务对应不同的Ip地址,注册中心可以动态感知到服务节点的变化。

服务消费方(Order 服务)需要调用提供方(Member 服务)提供的服务时,从中获取提供方的调用地址列表,然后进行调用。这个过程称为服务的订阅。

 

2.2服务注册原理

rpc框架会在的注册目录下,为每个应用创建一个持久节点,如order应用创建order持久节点,member应用创建member持久节点

然后在对应的持久节点下,为每个微服务创建一个临时节点,记录每个服务的URL等信息

如下:

1)引用zk客户端 相关依赖

org.apache.curator
curator-recipes
4.0.0
org.apache.curator
curator-framework
4.0.0

2)注册服务到zk

public class RegisterCenterImpl implements IRegisterCenter {    private CuratorFramework curatorFramework;    {        curatorFramework = CuratorFrameworkFactory.builder()                .connectString(ZkConfig.addr).sessionTimeoutMs(4000)                .retryPolicy(new ExponentialBackoffRetry(1000, 10)).build();        curatorFramework.start();    }    /**    * 服务注册    */    @Override    public void registry(String serverName, String serviceAddress) {        // 节点路径:/register/(serverName)        String serverPath = ZkConfig.ZK_REGISTER_PATH.concat("/").concat(serverName);        try {            // 每个应用创建一个持久节点            if (curatorFramework.checkExists().forPath(serverPath) == null) {                curatorFramework.create().creatingParentsIfNeeded()                        .withMode(CreateMode.PERSISTENT).forPath(serverPath, "0".getBytes());            }            // 为每一个微服务创建一个临时节点,注册成功            String addr = serverPath.concat("/").concat(serviceAddress);            String rsNode = curatorFramework.create().withMode(CreateMode.EPHEMERAL)                    .forPath(addr, "0".getBytes());            System.out.println("服务注册成功," + rsNode);        } catch (Exception e) {            e.printStackTrace();        }    }}

 

2.3服务动态发现原理

由于服务消费方向订阅了(监听)服务提供方,一旦服务提供方有变动的时候(增加服务或者减少服务),就会把最新的服务提供方列表(member list)推送给服务消费方,这就是服务动态发现的原理。

作者:Marvin Mai

来源:https://dwz.cn/6ByfGykc

一只 有深度 有灵魂 的公众号0.0

右上角按钮分享给更多人哦~

来都来了,点个在看再走吧~~~

转载地址:http://stlub.baihongyu.com/

你可能感兴趣的文章
使聊天机器人的对话更有营养
查看>>
一个 tflearn 情感分析小例子
查看>>
attention 机制入门
查看>>
手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
查看>>
GAN 的 keras 实现
查看>>
AI 在 marketing 上的应用
查看>>
Logistic regression 为什么用 sigmoid ?
查看>>
Logistic Regression 为什么用极大似然函数
查看>>
SVM 的核函数选择和调参
查看>>
LightGBM 如何调参
查看>>
用 TensorFlow.js 在浏览器中训练神经网络
查看>>
cs230 深度学习 Lecture 2 编程作业: Logistic Regression with a Neural Network mindset
查看>>
梯度消失问题与如何选择激活函数
查看>>
为什么需要 Mini-batch 梯度下降,及 TensorFlow 应用举例
查看>>
为什么在优化算法中使用指数加权平均
查看>>
什么是 Q-learning
查看>>
用一个小游戏入门深度强化学习
查看>>
5 分钟入门 Google 最强NLP模型:BERT
查看>>
初探Java设计模式4:一文带你掌握JDK中的设计模式
查看>>
初探Java设计模式5:一文了解Spring涉及到的9种设计模式
查看>>