Java经典框架之Zookeeper

Zookeeper

Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。
   

课程内容的介绍

1. Zookeeper的介绍和安装
2. Zookeeper客户端使用
3. ZookeeperJavaAPI使用
  

一、Zookeeper的介绍和安装

1. 为什么要使用Zookeeper
我们为了学习Dubbo,而在dubbo中需要一个注册中心,而Zookeeper是我们在使用Dubbo是官方推荐的注册中心,所以我们先来介绍Zookeeper。

     

  
2. Zookeeper介绍

    
2.1 Zookeeper概述
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
Zookeeper是一个分布式协调服务;就是为用户的分布式应用程序提供协调服务。

    
2.2 Zookeeper的集群机制
Zookeeper是为其他分布式程序提供服务的,所以本身自己不能随便就挂了,所以zookeeper自身的集群机制就很重要。zookeeper的集群机制采用的是半数存活机制,也就是整个集群节点中有半数以上的节点存活,那么整个集群环境可用。这也就是说们的集群节点最好是奇数个节点。
  
Zookeeper集群节点的角色
Leader
Leader服务器是Zookeeper集群工作的核心,其主要工作如下
1. 事务请求的唯一调度和处理者,保证集群事务处理的顺序性。
2. 集群内部各服务器的调度者。
  
Follower
Follower是Zookeeper集群的跟随者,其主要工作如下
1. 处理客户端非事务性请求(读取数据),转发事务请求给Leader服务器。
2. 参与事务请求Proposal的投票。
3. 参与Leader选举投票。
  
Observer
Observer充当观察者角色,观察Zookeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器进行处理。Observer不会参与任何形式的投票,包括事务请求Proposal的投票和Leader选举投票。
  
3. 集群环境准备
通过上面的介绍我们了解到zookeeper的集群环境应该配置奇数个节点,所以我们在本文中搭建的zookeeper环境准备在3个节点上搭建。接下来我们介绍下需要准备的环境。
  
3.1 准备3个节点
准备3个centos7.0的虚拟机节点,并且安装配置好JDK版本最好是8.不清楚的可参考此地址Linux之jdk安装,并配置好相关的网络配置。

  
通过VMware的克隆或者直接复制文件夹的方式来创建另外两个新的节点。
  
3.2 网络配置
修改ifcfg-ens33配置文件。

  
重启网络服务
service network restart
  
ping测试

  
三个节点的网络配置都ok的化我们就可以通过XShell来连接了。
  
3.3 节点的映射关系
每个节点设置相应的ip和主机名的映射关系,方便集群环境的部署。
修改hosts配置文件中的信息。

    
3.4 配置免密登录
生成公钥和私钥
ssh-keygen
  
输入命令后根据提示,四次回车即可。

  
发送公钥给需要免密登录的节点。
ssh-copy-id bobo01
ssh-copy-id bobo02
ssh-copy-id bobo03
  

  
节点和节点发送文件通过scp命令实现。
scp -r b.txt bobo01:/root/
  

  
3.5 关闭防火墙
查看防火墙状态
firewall-cmd --state
  
停止防火墙
systemctl stop firewall.service
  
禁止开机启动
systemctl disable firewall.service
  
4. Zookeeper集群环境搭建
4.1 获取安装文件
下载地址:https://mirrors.bfsu.edu.cn/apache/zookeeper/
通过wget命令将安装文件下载到opt目录下
注意:
apache-zookeeper-3.5.9-bin.tar.gz和apache-zookeeper-3.5.9.tar.gz的区别 -bin是编译后的文件 我们用这个。
wget https://mirrors.bfsu.edu.cn/apache/zookeeper/zookeeper-3.5.9/apache-zookeeper-3.5.9-bin.tar.gz
  

  
解压缩文件。

  
进入Zookeeper目录

   
4.2 修改配置
修改zoo.cfg文件,系统默认的名称是 zoo_smple.cfg我们需要重命名为zoo.cfg。

  
修改cfg的内容
修改了两块:
1是Zookeeper中存储数据的文件夹,还有就是Zookeeper集群环境节点信息。

  
配置myid文件
我们需要在Zookeeper的数据存储的目录中创建一个myid文件,文件中的内容只有一行信息,即表示我们集群几点的标识,范围是1-255,每个节点的myid的数字和我们在zoo.cfg中配置的server.数字是对应的。
1
   
4.3 分发文件
当我们配置好了一个Zookeeper节点后,我们就可以将Zookeeper文件夹分发给其他几个节点了。
scp -r zookeeper bobo02:`pwd`
scp -r zookeeper bobo03:`pwd`
  
分发成功后我们需要修改各个节点中的myid的信息为配置文件中对应的数字。
  
4.4 启动测试
整个集群环境都配置好了之后我们就可以测试启动了。
启动命令
./bin/zkServer.sh start
  
当我们仅仅启动一个节点的时候,因为半数存活机制,3个节点只启动一个节点是没有效果的。

  
当我们启动第二个节点后发现集群环境可以使用了。

  
然后第一个节点的状态也改变了。

  
然后再把第三个节点也启动起来。

  
5. Zookeeper的选举机制
为什么要进行Leader选举?
Leader 主要作用是保证分布式数据一致性,即每个节点的存储的数据同步。遇到以下两种情况需要进行。
Leader选举
服务器初始化启动。
服务器运行期间无法和Leader保持连接,Leader节点崩溃,逻辑时钟崩溃。
  
5.1 服务器初始化时Leader选举
Zookeeper由于其自身的性质,一般建议选取奇数个节点进行搭建分布式服务器集群。以3个节点组成的服务器集群为例,说明服务器初始化时的选举过程。启动第一台安装Zookeeper的节点时,无法单独进行选举,启动第二台时,两节点之间进行通信,开始选举Leader。
1. 每个Server投出一票。他们两都选自己为Leader,投票的内容为(SID,ZXID)。SID即Server的id,安装zookeeper时配置文件中所配置的myid;ZXID,事务id,为节点的更新程度,ZXID越大,代表Server对Znode的操作越新。由于服务器初始化,每个Sever上的Znode为0,所以Server1投的票为(1,0),Server2为(2,0)。两Server将各自投票发给集群中其他机器。
2. 每个Server接收来自其他Server的投票。集群中的每个Server先判断投票有效性,如检查是不是本轮的投票,是不是来Looking状态的服务器投的票。
3. 对投票结果进行处理。先了解下处理规则
首先对比ZXID。ZXID大的服务器优先作为Leader ,若ZXID相同,比如初始化的时候,每个Server的ZXID都为0,就会比较myid,myid大的选出来做Leader。
对于Server而言,他接受到的投票为(2,0),因为自身的票为(1,0),所以此时它会选举 Server2为Leader,将自己的更新为(2,0)。而Server2收到的投票为Server1的(1,0)由于比他自己小,Server2的投票不变。Server1和Server2再次将票投出,投出的票都为(2,0)。
4. 统计投票。每次投票之后,服务器都会统计投票信息,如果判定某个Server有过半的票数投它,那么该Server将会作为Leader。对于Server1和Server2而言,统计出已经有两台机器接收了(2,0)的投票信息,此时认为选出了Leader。
5. 改变服务器状态。当确定了Leader之后,每个Server更新自己的状态,Leader将状态更新为Leading,Follower将状态更新为Following。

    
5.2 服务器运行期间的Leader选举
Zookeeper运行期间,如果有新的Server加入,或者非Leader的Server宕机,那么Leader将会同步数据到新Server或者寻找其他备用Server替代宕机的Server。若Leader宕机,此时集群暂停对外服务,开始在内部选举新的Leader。假设当前集群中有Server1、Server2、Server3三台服务器,Server2为当前集群的Leader,由于意外情况,Server2宕机了,便开始进入选举状态。过程如下。
1. 变更状态。其他的非Observer服务器将自己的状态改变为Looking,开始进入Leader选举。
2. 每个Server发出一个投票(myid,ZXID),由于此集群已经运行过,所以每个Server上的ZXID可能不同。
假设Server1的ZXID为145,Server3的为122,第一轮投票中,Server1和Server3都投自己,票分别为(1,145)、(3,122),将自己的票发送给集群中所有机器。
3. 每个Server接收接收来自其他Server的投票,接下来的步骤与初始化时相同。
  

二、Zookeeper客户端使用

1. 配置Zookeeper的环境变量
为了简化我们每次操作Zookeeper而不用进入到Zookeeper的安装目录,我们可以将Zookeeper的安装信息配置到系统的环境变量中。
vim /etc/profile
  
添加的内容
export ZOOKEPPER_HOME=/opt/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin
  
执行source命令
source /etc/profile
  
我们就可以在节点的任意位置操作Zookeeper了。
通过scp命令将profile文件发送到其他几个节点上。
scp /etc/profile bobo02:/etc/
  
2.客户端连接
通过bin目录下的zkCli.sh 命令连接即可。
zkCli.sh
  

   
zkCli.sh默认连接的是当前节点的Zookeeper节点,如果我们要连接其他节点执行如下命令即可。
zkCli.sh -timeout 5000 -server bobo02:2181
  

  
3.数据操作
3.1 Zookeeper的数据结构
1. 层次化的目录结构,命名符合常规文件系统规范。
2. 每个节点在Zookeeper中叫做znode,并且有一个唯一的路径标识。
3. 节点znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)。
4. 客户端应用可以在节点上设置监听器。

    
3.2 节点类型
1).znode有两种类型:
短暂性(ephemeral)(断开连接自己删除)
持久性(persistent)(断开连接不删除)
  
2).znode有四种形式的目录节点(默认是persistent)如下

  
创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,有父节点维护。
在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序。
  
3.3 常用命令
Zookeeper作为Dubbo的注册中心用来保存我们各个服务的节点信息,显示Zookeeper是可以实现输出的存储操作的,我们来看下Zookeeper中存储操作的基本命令。

  
ls
ls用来查看某个节点下的子节点信息。

  
增强的命令,查看节点下的子节点及当前节点的属性信息 ls2或者 ls -s 命令。

  
create
创建节点信息

  
get
get命令用来查看节点的数据。

  
如果要查看节点的属性信息那么我们可以通过get -s 来实现。

  
delete
delete只能删除没有子节点的节点要删除非空节点可以通过 rmr 或者 deleteall 命令实现。

  
set
set命令可以用来修改节点的内容。

  
3.4 事件监听
3.4.1 数据改变的监听
监听某个节点的数据内容变化,通过get命令 带 -w 参数即可,在3.4版本的Zookeeper中是通过 get path watch 来说实现监控的。

  
然后我们在其他节点上修改app1节点的数据,会触监听事件。

  

  
注意监听一次节点只会触发一次,如果要实现多次监听,那么可以在触发事件的处理函数中再次追加对节点的监听操作。
  
3.4.2 子节点的改变
监听节点下面的子节点的改变。
[zk: localhost:2181(CONNECTED) 14] ls -w /app1
[]
  
触发

  

  

三、Zookeeper Java API使用

介绍如何通过Java代码来操作Zookeeper中的数据。
在Zookeeper的安装目录下是提供的有相关的Jar依赖的。

  
但是我们对于Maven构建项目已经习惯而且是主流,那么我们可以通过maven坐标来管理。
    <dependencies><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.5.9</version></dependency><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
  
1. API的使用
1.1 连接ZK服务
package com.bobo.test;import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;import java.io.IOException;public class Test1 {private String connectString = "192.168.100.121:2181,192.168.122:2181,192.168.100.122:2181";private int sessionTimeOut = 5000;/*** 连接Zookeeper服务端*/@Testpublic void test1() throws IOException {zooKeeper = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {/*** 触发监听事件的回调方法* @param watchedEvent*/@Overridepublic void process(WatchedEvent watchedEvent) {System.out.println("触发了.....");}});//System.out.println("--->" + zooKeeper);}}
  

  
1.2 基本操作
package com.bobo.test;import jdk.nashorn.internal.ir.CallNode;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.util.List;public class Test1 {private String connectString = "192.168.100.121:2181,192.168.122:2181,192.168.100.122:2181";private int sessionTimeOut = 10000;ZooKeeper zooKeeper = null;/*** 连接Zookeeper服务端*/@Beforepublic void test1() throws IOException {zooKeeper = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {/*** 触发监听事件的回调方法* @param watchedEvent*/@Overridepublic void process(WatchedEvent watchedEvent) {System.out.println("触发了.....");}});//System.out.println("--->" + zooKeeper);}/*** 创建节点*/@Testpublic void createNode() throws Exception{String path = zooKeeper.create("/apptest" // 节点路径,"HelloZookeeper".getBytes() // 节点的数据, ZooDefs.Ids.OPEN_ACL_UNSAFE // 权限, CreateMode.PERSISTENT // 节点类型);System.out.println(path);}/*** 判断节点是否存在*/@Testpublic void exist() throws  Exception{// true表示的是使用Zookeeper中的watchStat stat = zooKeeper.exists("/apptest", true);if(stat != null){System.out.println("节点存在"+ stat.getNumChildren());}else{System.out.println("节点不存在 ....");}}/*** 获取某个节点下面的所有的子节点*/@Testpublic void getChildrens() throws Exception{List<String> childrens = zooKeeper.getChildren("/app1", true);for (String children : childrens) {// System.out.println(children);// 获取子节点中的数据byte[] data = zooKeeper.getData("/app1/" + children, false, null);System.out.println(children+":" + new String(data));}}/*** 修改节点的内容*/@Testpublic void setData() throws Exception{// -1 不指定版本 自动维护Stat stat = zooKeeper.setData("/app1/a1", "666666".getBytes(), -1);System.out.println(stat);}/*** 删除节点*/@Testpublic void deleteNode() throws Exception{zooKeeper.delete("/app1",-1);}}
  
1.3 事件监听处理
Java程序如何监听Zookeeper中的数据的变化?
    /*** 监听Node节点下的子节点的变化*/@Testpublic void nodeChildrenChange() throws Exception{List<String> list = zooKeeper.getChildren("/app1", new Watcher() {/***              None(-1),*             NodeCreated(1),*             NodeDeleted(2),*             NodeDataChanged(3),*             NodeChildrenChanged(4),*             DataWatchRemoved(5),*             ChildWatchRemoved(6);* @param watchedEvent*/@Overridepublic void process(WatchedEvent watchedEvent) {System.out.println("--->"+ watchedEvent.getType());}});for (String s : list) {System.out.println(s);}Thread.sleep(Integer.MAX_VALUE);}/*** 监听节点内容变更*/@Testpublic void nodeDataChanged() throws Exception{byte[] data = zooKeeper.getData("/app1/a1", new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {System.out.println("--->" + watchedEvent.getType());}}, null);System.out.println("--->" + new String(data));Thread.sleep(Integer.MAX_VALUE);}

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

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

相关文章

程序性能优化全能手册

本文聊一个程序员都会关注的问题&#xff1a;性能。 当大家谈到“性能”时&#xff0c;你首先想到的会是什么&#xff1f; 是每次请求需要多长时间才能返回&#xff1f; 是每秒钟能够处理多少次请求&#xff1f; 还是程序的CPU和内存使用率高不高&#xff1f; 这些问题基本上…

Visual Studio Code安装C#开发工具包并编写ASP.NET Core Web应用

前言 前段时间微软发布了适用于VS Code的C#开发工具包&#xff08;注意目前该包还属于预发布状态但是可以正常使用&#xff09;&#xff0c;因为之前看过网上的一些使用VS Code搭建.NET Core环境的教程看着还挺复杂的就一直没有尝试使用VS Code来编写.NET Core。不过听说C# 开发…

C++结合OpenCV:图像的基本表示方法

1.二值图像 二值图像是指仅仅包含黑色和白色两种颜色的图像。在计算机中&#xff0c;通过一个栅格状排列的数据集&#xff08;矩阵&#xff09;来表示和处理图像。例如&#xff0c;图1是一个字母A的图像&#xff0c;计算机在处理该图像时&#xff0c;会首先将其划分为一个个的小…

6 网关和配置服务器

文章目录 网关模式Spring Cloud网关Spring Cloud网关微服务其他项目的变更运行和测试小结 运行状况Spring Boot Actuator在微服务中包含Actuator 服务发现和负载均衡ConsulSpring Cloud ConsulSpring Cloud负载均衡器网关中的服务发现和负载均衡使用服务发现和负载均衡 环境配置…

数据库开发之事务和索引的详细解析

2. 事务 场景&#xff1a;学工部整个部门解散了&#xff0c;该部门及部门下的员工都需要删除了。 操作&#xff1a; -- 删除学工部 delete from dept where id 1; -- 删除成功 ​ -- 删除学工部的员工 delete from emp where dept_id 1; -- 删除失败&#xff08;操作过程中…

windows下载官方正版notepad++

一、前言 notepad是一款非常好用的编辑器&#xff0c;简洁、快速、高效。可是很多时候我们想去官网下载时&#xff0c;百度出来的都是一堆第三方下载地址&#xff0c;捆绑流氓软件&#xff0c;要么就是付费&#xff0c;作为一款优秀开源软件&#xff0c;我们必须要知道正确的下…

用Redis实现全局唯一ID

全局唯一ID 如果使用数据库自增ID就存在一些问题&#xff1a; id的规律性太明显受表数据量的限制 全局ID生成器&#xff0c;是一种在分布式系统下用来生成全局唯一ID的工具&#xff0c;一般要满足下列特性&#xff1a; 唯一性高可用递增性安全性高性能 为了增加ID的安全性…

Linux环境变量、export命令、env命令、$符号

一、环境变量 我们所使用的一系列命令本质上就是一个个的可执行程序 不管我们当前的工作目录在何处&#xff0c;命令都可以准确执行&#xff0c;这就是环境变量的作用&#xff0c;是借助环境变量中PATH的值来做到的&#xff0c;PATH记录了系统执行任何命令的搜索路径 环境变量…

ansible 配置jspgou商城上线(MySQL版)

准备环境 准备两台纯净的服务器进行&#xff0c;在实验之前我们关闭防火墙和selinux systemctl stop firewalld #关闭防火墙 setenforce 0 #临时关闭selinux hosts解析(两台服务器都要去做) [rootansible-server ~]# vim /etc/hosts 10.31.162.24 ansible-ser…

博客的简介

博客的简介 大家可以把这个当做目录&#xff0c;从中选择自己需要的内容进行阅览&#xff0c;欢迎大家一键三连&#xff01;&#xff01;&#xff01;&#xff01; 话题讨论专栏 点击进入话题讨论专栏 主要文章&#xff1a; 神奇的代码——可随意修改复制页面内容 Python…

系统安全及应用

1、基本安全措施 1.1、系统账号清理 在Linux系统中&#xff0c;除了用户手动创建的各种账号之外&#xff0c;还包括随系统或程序安装过程而生产的其他大量账号。除了超级用户root之外&#xff0c;其他大量账号只是用来维护系统运作、启动或保持服务进程&#xff0c;一般是不允…

Java:Lambda表达式、方法引用

文章目录 1、Lambda表达式1.1 Lambda表达式体验1.2 Lambda表达式的省略形式1.3 Lambda表达式练习 2、方法引用体验3、方法引用符4、引用静态方法5、引用对象的实例方法6、引用类的实例方法7、引用构造方法8、引用数组的构造方法9、方法引用练习9.1 练习19.2 练习29.3 练习3 10、…

优势演员-评论家算法 A2C

优势演员-评论家算法 A2C 优势演员-评论家算法 A2C主要思想目标函数 优势演员-评论家算法 A2C 前置知识&#xff1a;演员-评论家算法&#xff1a;多智能体强化学习核心框架 主要思想 AC 网络结构&#xff1a; 策略网络 - 演员: 这个网络负责根据当前的状态选择动作。它输出的是…

leetcode——杨辉三角

https://leetcode.cn/problems/pascals-triangle/ 杨辉三角&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 核心思想&#xff1a;找出杨辉三角的规律&#xff0c;发…

案例098:基于微信小程序的电子购物系统的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

Apache Paimon:Streaming Lakehouse is Coming

摘要&#xff1a;本文整理自阿里云智能开源表存储负责人&#xff0c;Founder of Paimon&#xff0c;Flink PMC 成员李劲松&#xff08;花名&#xff1a;之信&#xff09;、同程旅行大数据专家&#xff0c;Apache Hudi & Paimon Contributor 吴祥平、汽车之家大数据计算平台…

前置判断-Detection

检测模型回答存在幻觉可以通过检索外部知识进行校验&#xff0c;不过考虑生成式模型覆盖问题的广泛性&#xff0c;Self-Contradictory论文中评估chatgpt生成的回答中38.5%的内容无法通过Wiki等外部知识进行校验。 因此这里我们先介绍一种完全基于模型自身&#xff0c;不依赖外…

多线程第一课---

UML中规定的箭头方向是从子类指向父类。 关于这一点&#xff0c;按照以下方法去理解有助于大家记住这条规则。 在定义子类时需要通过extends关键字指定父类。因此&#xff0c; 子类一定要知道父类的定义&#xff0c;而反过来&#xff0c;父类并不知道子类的定义。 只有在知道对…

51单片机串行口相关知识

51单片机串行口相关知识 串行通信概念 计算机与外部通信方式就两种&#xff1a; 并行通信串行通信 两种通信方式的特点以及适用场景&#xff1a; 名称特点适用场景并行通信速度快&#xff0c;效率高&#xff0c;成本高适合短距离高速通信&#xff0c;如计算机内部各硬件之…

基于日照时数计算逐日太阳辐射

基于日照时数计算逐日太阳辐射