- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章ZooKeeper分布式配置,看这篇就够了由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
PS:这个不重要,不感兴趣的,可以直接看下面 。
来源:《从 Paxos 到 ZooKeeper 》 。
ZooKeeper 最早起源于雅虎研究院的一个研究小组,在当时,研究人员发现,在雅虎内部有很多的大型系统基本上都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点的问题,所有雅虎的开发人员就尝试开发了一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在处理业务逻辑上。关于"ZooKeeper"这个项目的名字。也有一个故事,在项目开始初期,因为考虑到内部的很多项目都是用动物的名字来命名的(例如:Pig项目),所以雅虎的工程师也希望给这个项目也取一个动物的名字,这个时候担任研究院的首席科学家 Raghu Ramakrishnan 开玩笑地说:“在这样下去,我们这儿就变成动物园”,此话一出,大家纷纷表示就叫动物园管理员吧,因为各个以动物命名的分布式组件放在一起,这个分布式系统看上去就像一个大型的动物园了,而ZooKeeper 正好要用来进行分布式环境的协调,于是ZooKeeper 的名字也就由此诞生了.
在上一期中我们讲解了 ZooKeeper集群的配置和安装,ZooKeeper集群 主要是帮我们做分布式协调的,今天我们用ZK实现分布式配置。关于ZooKeeper 集群的配置大家可以参考上一篇文章《Zookeeper 集群部署的那些事儿》.
对于刚开始的时候,很多公司的服务器可能是由单个组成,但是随着业务的发展,单一节点的服务无法满足业务的飞速发展,后面就出现了分布式、集群的概念,到了现在形成的微服务,技术的改进能够更好的满足业务的需要.
假设我们线上有很多个微服务分布在不同的服务器上,其中一个微服务,我们就叫它 goods-service,当 goods-service的IP地址需要变更的时候,但是 goods-service又对很多其他的程序提供了服务,这个时候如果没有一个统一配置的东西,每一个应用到 goods-service的应用程序都要做相应的IP地址修改,这是一个很麻烦的事情.
如果使用ZooKeeper来做分布式配置的话,是可以解决这个问题的.
如果我们只考虑服务治理的话,Eureka是比较合适的,Eureka是比较纯粹的注册中心了,和Eureka不同Apache ZooKeeper 在设计的时候就遵循 CP原则,任何时候对 ZooKeeper 的访问请求都能得到一致的数据结果,同事系统对网络分割具有容错性,今天我们讲解的就是关于ZooKeeper 的注册发现.
低延迟: 配置改变( create/update/delete)后能够最快的把最新的配置同步到其他节点中 。
高可用: 配置中心可以稳定的对外提供服务 。
其中 低延迟 我们可以通过 ZooKeeper 的 Watcher 机制来实现(等下会讲到Watcher机制)。约定一个节点用来存放配置信息,每个客户端都来监听这个节点的NodeDataChanged事件,当配置发生改变时将最新的配置更新到这个节点上,谁更新无所谓,任何节点都可以更新,当这个节点触发 NodeDataChanged 事件后,在去通知所有监听这个节点的客户端去获取这个节点的最新信息,因为watcher 是一次性的,所以当我们在获取最新信息的时候需要设置监听事件,大部分查询信息都是具有原子性的,所以ZooKeeper中的 getData 也是具有原子性操作,能够保证我们取得的信息是最新的.
对于 高可用 我们首先需要保证的多集群操作来进行ZooKeeper进行部署,在代码层不太需要做过多的工作.
Watch 是 ZooKeeper 针对节点的一次性观察者机制,就如同我们上面 * 低延迟* 中讲到的,一次触发后就失效,需要手工重新创建Watch.
当Watch监视的数据发生变化的时候,就会通知设置了 Watch 的客户端,就是我们API中的Watcher,Watcher机制就是为了监听Znode节点发生了哪些变化,所以会有对应的事件类型和状态类型,用过代码中switch进行监听,一个客户端可以链接多个节点,只要Znode节点发生变化就会执行 process(WatchedEventevent).
如下图所示:
从上图中我们可以看到,在ZooKeeper中,Watch采用的是推送机制,而不是客户端轮询,有些中间件采用的是拉取的模式,例如:KafKa.
Watch有两种监听模式,分别为 事件类型和状态类型 :
事件类型:Znode 节点关联,主要是针对节点的操作 。
状态类型:客户端关联,主要是针对于ZooKeeper集群和应用服务之间的状态的变更 。
一次性触发: 对于ZooKeeper的Watcher事件,是一次性触发的,当 Watch 监视的数据发生变化的时候,通知设置当前Watch 的 Client,就是我们对应的 Watcher,因为ZooKeeper 的监控都是一次性的,所以我们需要在每次触发后设置监控.
客户端串行执行: 客户端Watcher回调的过程是一个串行同步的过程,可以为我们保证顺序的执行.
轻量级: WatchedEvent是ZooKeeper整个Watcher通知机制的最小通知单元,总共包含三个部分(通知状态、事件类型和节点路径),Watcher通知,只会告诉客户端发生事件而不会告知具体内容,需要客户端主动去进行获取,比如 当监听到 WatchedEvent.NodeDataChanged 信息变化的时候,只会告诉我们这个节点的数据发生了变更,你快来获取最新的值吧.
客户端设置的每个监视点与会话关联,如果会话过期,等待中的监视点将会被删除。不过监视点可以跨越不同服务端的连接而保持,例如,当一个ZooKeeper客户端与一个ZooKeeper服务端的连接断开后连接到集合中的另一个服务端,客户端会发送未触发的监视点列表,在注册监视点时,服务端将要检查已监视的znode节点在之前注册监视点之后是否已经变化,如果znode节点已经发生变化,一个监视点的事件就会被发送给客户端,否则在新的服务端上注册监视点。这一机制使得我们可以关心逻辑层会话,而非底层连接本身.
ZooKeeper 注册的时候会向ZooKeeper 服务端请求注册,服务端会返回请求响应,不管成功失败,都会返回响应结果,当响应成功的时候,ZooKeeper服务端会把Watcher对象放到客户端的WatchManager管理并返回响应给客户端 。
FinalRequestProcessor.ProcessRequest()会判断当前请求是否需要注册Watcher 。
如果ZooKeeper判断当前客户端需要进行Watcher注册,会将当前的ServerCnxn 对象和数据路径传入 getData 方法中去。ServerCnxn 是ZooKeeper 客户端和服务端之间的连接接口,代表了一个客户端和服务端的连接,可以将 ServerCnxn 当做一个 Watcher 对象,因为它实现了 Watcher 的 process 接口.
WatcherManager 。
WatcherManager是 ZK服务端 Watcher 的管理器,分为 WatchTable 和 Watch2Paths 两个存储结构,这两个是不同的存储结构 1)WatchTable:从数据节点路径的颗粒度管理 Watcher 2)Watch2Paths:从Watcher的颗粒度来控制时间出发的数据节点 。
在服务端,DataTree 中会托管两个 WatchManager, 分别是 dataWatches (数据变更Watch) 和 childWatches(子节点变更Watch).
Watcher 触发逻辑 。
1)封装WatchedEven:将(KeeperState(通知状态),EventType(事件类型),Path(节点路径))封装成一个 WatchedEvent 对象 2)查询Watcher:根据路径取出对应的Watcher,如果存在,取出数据同时从 WatcherManager(WatchTable/Watch2Paths) 中删除 3)调用Process方法触发Watcher 。
4.客户端回调 Watcher 。
1)反序列化:字节流转换成 WatcherEvent 对象 2)处理 chrootPath:如果客户端设置了 chrootPath 属性,那么需要对服务器传过来的完整节点路径进行 chrootPath 处理,生成客户端的一个相对节点路径。比如(/mxn/app/love,经过chrootPath处理,会变成 /love) 3)还原 WatchedEvent:WatcherEvent 转换成 WatchedEvent 4)回调 Watcher:将 WatcherEvent 对象交给 EventThread 线程,在下一个轮询周期中进行 Watcher 回调 。
EventThread 处理时间通知 。
1) SendThread 接收到服务端的通知事件后,会通过调用 EventThread.queueEvent 方法将事件传给 EventThread 线程 2)queueEvent 方法首先会根据该通知事件,从 ZKWatchManager 中取出所有相关的 Watcher 客户端识别出 事件类型 EventType 后,会从相应的 Watcher 存储 (即3个注册方法( dataWatches、existWatcher 或 childWatcher)中去除对应的 Watcher 3) 获取到相关的所有 Watcher 后,会将其放入 waitingEvents 这个队列去 。
下面我们就来演示如何使用代码来实现ZooKeeper的配置 。
首先我们需要引入ZK的jar 。
既然我们要做的是分布式配置,首先我们需要模拟一个配置,这个配置用来同步服务的地址 。
创建ZooKeeper的时候,我们需要一个Watcher进行监听,后续对Znode节点操作的时候,我们也需要使用到Watcher,但是这两类的功能不一样,所以我们需要定义一个自己的watcher类,如下所示:
由于是异步进行操作的,我们创建一个ZooKeeper对象之后,如果不进行阻塞操作的话,有可能还没有连接完成就执行后续的操作,所以这里我们用 CountDownLatch进行阻塞操作,当监测连接成功后,进行 countDown放行,执行后续的ZK的动作.
当我们连接成功 ZooKeeper 之后,我们需要通过 exists判断是否存在节点,存在就进行 getData操作。这里我们创建一个 WatchCallBack因为 exists和getData都需要一个callback,所以除了实现Watcher以外还需要实现 节点状态:AsyncCallback.StatCallback数据监听:AsyncCallback.DataCallback 。
当前面准备好了之后,我们可以编写测试用例了:
测试类:
首先我们要知道,因为我们连接IP的时候加上了 /mxn这个目录结构,所以我们在服务器初始状态就必须要有这个节点:
集群初始状态:
我们启动程序看看 。
连接成功 。
ZooKeeper 下 /mxn 现在也是空 。
现在我们来创建一个 /mxn/myZNode节点数据 。
可以看到,创建完成之后,程序马上给出响应,打印出了我配置的值,muxiaonong666 。
此时,再设置 /mxn/myZNode的值为 muxiaonong6969 。
啪,很快啊!!!我们就可以看到值瞬间改变了 。
这个时候我们如果删除 /mxn/myZNode节点,会发生什么呢,前面我们已经写了watch,如果Znode被删除了,,watch and callback执行 。
删除 /mxn/myZNode 节点 。
我们可以看到前面还在打印数据,后面就提示丢失.
但是这个时候我们客户端没有关闭,而是还在等待数据的更新,如果这个时候当重新进行创建 /mxn/myZNode节点的时候,程序又会继续疯狂输出.
程序正常运行,并且成功获取到了zk配置的最新数据,到这里基本上就实现了,ZooKeeper的分布式配置中心功能了 。
在这里我测试用的是 getData,但是在项目实战用可能用的更多的是 子节点的操作 getChildren 。
到这里我们这篇 ZooKeeper分布式配置注册发现 就讲完了,如果有疑问的地方欢迎进行讨论,ZooKeeper 可以作为分布式配置中心,也可以用来当然微服务的注册,不过现在微服务都有自己的一套服务发现,对于了解ZooKeeper可以我们方便我们在进行技术选型的时候更好的去抉择, ZooKeeper 的高可用和最终一致性也是比较稳定.
本文代码地址:https://github.com/muxiaonong/ZooKeeper/tree/master/mxnzookeeper 。
原文链接:https://mp.weixin.qq.com/s/FD8q1CIZDxWheRmXeRbl3A 。
最后此篇关于ZooKeeper分布式配置,看这篇就够了的文章就讲到这里了,如果你想了解更多关于ZooKeeper分布式配置,看这篇就够了的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我只是不喜欢 Logback 的 XML 或 Groovy 配置,而更喜欢用 Java 进行配置(这也是因为我将在初始化后的不同时间在运行时更改配置)。 似乎对 Logback 进行 Java 配置的
我的 sphinx 配置是: ================================ config/sphinx.yml development: bin_path: "/usr/loc
我们计划在生产服务器中部署我们的系统。我有兴趣了解更多有关优化网站性能的信息。 Sitecore 有哪些优化建议? (缓存,网络配置中的其他设置) 我们可以在 IIS 中做哪些优化? 找不到关于这些主
我有一个 Django 应用程序,可以处理网站的两个(或更多)部分,例如网站的“admin”和“api”部分。我还为网站的其余部分提供了普通的 html 页面,其中不需要 Django。 例如,我希望
我刚刚开始研究Docker。我有一个 Node 应用程序,可以调整大小和图像,然后在完成后向 aws 发送 SQS 消息。我已成功创建应用程序的 docker 镜像,并从本地计算机复制它,但遇到了无法
如何配置 checkstyle(在 Ant nt Maven 中)任务?我尝试了一点,但没有正确收到报告。这是我的 Ant 脚本。
我正在使用 Quartz 和 Spring 框架重写一个遗留项目。原始配置是 XML 格式,现在我将其转换为 Java Config。 xml 配置使用 jobDetail 设置触发器 bean 的作
tl;rd: 使用主键对数据库进行分区 索引大小问题。 数据库大小每天增长约 1-3 GB 突袭设置。 您有使用 Hypertable 的经验吗? 长版: 我刚刚建立/购买了一个家庭服务器: 至强 E
在安装 gcp 应用程序后,我们尝试使用 GCP 的图形 api 配置 Azure Active Directory saml 配置。我们正在遵循相同的 AWS graph api saml 设置 U
我刚刚了解了 spring security 并想使用 java hibernate 配置连接到数据库,但我发现的示例或教程很少。我通过使用 xml 配置找到了更多。我在这里使用 Spring 4.0
我们最近切换到 Java 8 以使用 java.time API(LocalDate、LocalDateTime,...)。因此,我们将 Hibernate 依赖项更新到版本 4.3.10。我们编写了
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《quarkus实战》系列的第六篇,咱
我是 NGINX 的新手,我正在尝试对我们的 ERP 网络服务器进行负载平衡。我有 3 个网络服务器在由 websphere 提供支持的端口 80 上运行,这对我来说是一个黑盒子: * web01.e
我们想使用 gerrit 进行代码审查,但我们在 webview 中缺少一些设置。 是否可以禁止提交者审查/验证他们自己的 提交? 是否有可能两个审稿人给 +1 一个累积它 到+2,以便可以提交? 谢
配置根据运行模式应用于 AEM 实例。在多个运行模式和多个配置的情况下,AEM 如何确定要选择的配置文件?假设以下配置在 AEM 项目中可用, /apps /myproject - con
我正在使用 Neo4j 服务器。我遇到了负载相对较低的问题。但是,响应时间相当长。我认为为请求提供服务的线程数太少了。有没有办法调整为 HTTP 请求提供服务的线程池的大小。那可能吗? 最佳答案 线程
我在/etc/default/celeryd 中有以下配置 CELERYD_NODES = "worker1 worker2 worker3" CELERYD_CHDIR = "path to pro
Plone 在其页面中显示来 self 的母语(巴西葡萄牙语)的特殊字符。但是,当我使用我创建的 spt 页面时,它会显示转义序列,例如: Educa\xc3\xa7\xc3\xa3o 代替 Educ
我正在尝试开始使用 Emacs/Clojure。安装 emacs 扩展的正确方法是什么。我正在尝试安装以下插件: https://bitbucket.org/kotarak/vimclojure 我已
我有一个简单的 C 项目结构: proj/ src/ docs/ build/ tests/ lib/ 尝试编写合适的 CMake 文件。 到目前为止我的尝试:http://pas
我是一名优秀的程序员,十分优秀!