Zookeeper与Dubbo微服务实战之Zookeeper篇
发布日期:2021-05-07 14:08:10 浏览次数:24 分类:精选文章

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

文章目录

zookeeper环境搭建

linux下jdk环境搭建

一、安装jdk

1、将jdk和zookeeper通过ftp转移到linux /home下
2、解压jdk和zookeeper到/usr/和/usr/local下
解压jdk和zookeeper
tar -zxvf ....jdktar -zxvf ...zookeeper
修改解压之后的jdk和zookeeper的名字
mv XXX jdk8mv YYY zookeeper
转移jdk和zookeeper
mv jdk8 /usrmv zookeeper /usr/local
2、配置jdk和zookeeper环境变量
修改配置文件 vim /etc/profile
export JAVA_HOME=/usr/jdk8export ZOOKEEPER_HOME=/usr/local/zookeeperexport CLASSPATH=.:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jarexport PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin
配置完环境变量测试一下是否成功
测试之前先刷新配置文件
source /etc/profile//测试java -version

二、zookeeper配置文件

复制zookeeper/conf/zookeeper.cfg文件

cp zookeeper.cfg zoo.cfg

1、tickTime

Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔。 也就是每隔 tickTime 时间就会发送一个心跳。以毫秒为单位,比如session超时 N*tickTime

2、initLimit

用于集群,允许从节点链接并同步到master节点的初始化连接时间,以tickTime的倍数来表示。

3、syncLimit

用于集群,master主节点与从节点之间发送消息,请求和应答时间长度(心跳机制),超时从节点就会被抛弃

4、dataDir

必须配置

但是不能配置到临时文件夹里面
dataDir=/tmp/zookeeper
修改为
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir

5、dataLogDir

日志目录,如果不配置会和dataDir公用

6、clientport

连接服务器的端口,默认2181

三、启动zookeeper

//启动./zkServer.sh start//重启,现关闭再开启./zkServer.sh restart//查看状态./zkServer.sh status

3-1 zk数据模型介绍

1、树形结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ygF1mlkK-1575608668526)(en-resource://database/1749:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-djztQuLN-1575608668527)(en-resource://database/1751:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vc99c9ml-1575608668528)(en-resource://database/1753:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YGV94rXQ-1575608668528)(en-resource://database/1755:1)]

3-2 zookeeper数据模型的基本操作

  1. 客户端连接
    ./zkCli.sh打开命令行后台
    连接到Connecting to localhost:2181
    Ctrl+C退出当前客户端
  2. 查看znode结构
  3. 关闭客户端连接

3-3 zookeeper的作用

1、高可用,当master挂了之后,后续的从节点就会替补上去,不让让系统崩掉,这也叫做首脑模式,保证集群的高可用,高可用的体现之一,局长死了,副局长立马顶上

2、统一配置文件管理,只需要部署一台服务器,则可以吧相同的配置文件同步更新到其他服务器,此操作在云计算中非常多(假设修改了redis统一配置)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZGMp7qyF-1575608668529)(en-resource://database/1757:1)]
3、发布与订阅,例如消息队列MQ,发布者将信息发布到节点,二订阅了节点的订阅者就会收到这个信息,相应的进行改变
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ic7PjXA0-1575608668530)(en-resource://database/1759:1)]
4、提供分布式锁,分布式环境中,不同进程的资源争抢,类似以多线程中的锁(为什么zookeeper能提供分布式锁呢,归因于zookeeper的结构,在zookeeper的结构中,增加节点是往后续的,即一个个增加在后面,类似于队列,所以第一个就是相当于master,这个唯一就是锁)
5、集群管理,集群保证数据的强一致性
比如客户端连接了主节点,并且增加数据Data-XYZ,那么由于集群的机制会进行同步,那么从节点酒也有了这个数据,客户端断开之后,连接其他节点也会读到相同的信息(类似于2统一文件-配置)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xgLMpyzY-1575608668530)(en-resource://database/1761:1)]

4-1 zookeeper的常用命令

  1. ./zkCli.sh 打开命令行后台
  2. ls和ls2
    ls查看目录 ls /zookeeper
    ls2是查看节点状态信息 ls2 /
    ls2相当于ls和stat
  3. stat 查看状态信息
  4. get 当前节点的数据取出来
    czxid 节点创建的id
    ctime 节点创建的时间
    mzxid 节点修改的id
    mtime 节点修改的时间
    pzxid 子节点的id
    cversion 子节点的版本
    dataVersion 数据的版本
    aclVersion 节点权限修改的版本
    ephemeralOwner 之后再说
    dataLength 数据长度
    numChildren 下面子节点的个数

4-2 session的基本原理

基本原理一
  1. 客户端与服务器之间的连接存在会话
  2. 每个会话都会可以设置一个超时时间
  3. 心跳结束,则Session过期
    因为每个心跳都会向服务器发送一个(ping包?)信息,从而保证服务器知道session还活着
基本原理二
  1. Session过期,则临时节点znode会被抛弃
  2. 心跳机制:客户端向服务器的ping包请求
创建节点
创建默认节点(持久存在)

create /imooc immoc-data

创建临时节点(断开连接后,心跳结束不存在)

cerate -e /imooc/tmp tmp-data

如何识别是临时节点?

不是临时节点:ephemeralOwner=0x0
是临时节点::ephemeralOwner=0x0…
当zookeeper连接关闭时,临时节点不会立马被删除,临时节点默认存在一个心跳时间,等这个时间过后才会被删除

创建顺序节点(持久存在)

create -s /immoc/seq seq-data

ls /imooc
[seq0000000001]

创建的顺序节点从1开始

create -s /imooc/seq seq-data

ls /imooc
[seq0000000001, seq0000000002]
创建时节点序号是依次递增的

修改节点

set [-s] [-v version] path data

set /imooc new-data 修改之后,mtime、dataVersion、dataLength就会发生变化

dataVersion递增1

在指定版本号的节点,进行修改的情况

①、set -v 1 /imooc new

②、set -v 1 /imooc new

发生错误version No is not valid : /imooc

原因是①更新节点之后,dataVersion自增1变为了2,②更新的时候版本号已经不是1了,所以才会导致版本号不可校验,这可以做到乐观锁的效果,所以在并发的时候,由于版本号的问题,就不会导致并发错误

所以只能修改最新版本号的节点(不加版本号,默认修改最新版本的节点),修改其他版本的节点,就会出错

删除节点

delete [-v version] path

其他问题同上述修改节点

4-3 zk特性 watcher机制

一:

  1. 针对每个节点的操作,都会有一个监督者→watcher
  2. 当监控的某个对象(znode)发生变化,则触发watcher事件
  3. zk中的watcher是一次性的,触发后立即销毁

二:

  1. 父节点、子节点都能触发watcher
  2. 针对不同的操作,watcher能表现不同的反应
    (子)节点删除事件
    (子)节点修改事件
    (子)节点变化事件
    当(子)节点发生变化时,触发watcher相应的事件,客户端在收到这个事件之后,比对事件名,然后做出自己的操作,比如节点发出删除事件,watcher发送给客户端,客户端接收到这个事件之后,匹配成功,然后再删了与这个节点的连接

4-4 父节点watcher事件

  1. 创建父节点触发:NodeCreate

使用 stat [-w] path 为节点添加watcher

增加imooc节点的watcher
stat -w /imooc
创建/imooc节点
create /imooc watcher-test
WATCHER::WatchedEvent state:SyncConnected type:NodeCreated path:/imooc

  1. 修改父节点数据触发:NodeDataChanged

使用 get -w path为节点添加watcher

get -w /imooc
set /imooc new-data
WATCHER::WatchedEvent state:SyncConnected type:NodeDataChanged path:/imooc

  1. 删除父节点触发:NodeDeleted

使用 get -w path为节点添加watcher

get -w /imooc
delete /imooc
WATCHER::WatchedEvent state:SyncConnected type:NodeDeleted path:/imooc

4-5 子节点watcher事件

  1. ls为父节点(必须先存在父节点)设置watcher,创建子节点触发:NodeChildrenChanged
  2. ls为父节点设置watcher,删除子节点触发:NodeChildrenChanged
  3. ls为父节点设置watcher,修改子节点不触发事件
    如果需要让子节点触发事件,那么就需要在这各自节点上设置watcher事件,触发NodeChanged事件

4-6 watcher使用场景

统一资源配置

4-7 权限ACL

ACL(Access control lists)权限控制
  1. 针对节点可以设置相关读写等权限,目的是为了保证数据安全性
  2. 权限permissions可以指定不同的权限范围以及角色
ACL命令行
  1. getAcl 得到某个节点路径的acl权限信息
    getAcl path
  2. setAcl 设置某个节点路径的acl权限
    setAcl path acl
  3. addauth 输入认证授权信息,注册时输入明文密码(登录)但是在zk的系统中,密码是以加密的形式存在的
    addauth scheme auth
ASL的构成一
  1. zk的acl是通过[scheme🆔permission]来构成权限列表

scheme:权限模式,代表采用的某种权限机制,五种(常用四种)

id:代表允许访问的用户
permission:权限组合字符串

ACL的构成二 - Scheme
  1. world:world下只有一个id,那就是anyone,组合写法就是world:anyone:[permissions]
  2. auth:代表认证登录,需要注册用户有权限就可以,形式为:auth:user:password:[permissions]
  3. digest:需要对密码加密才能访问,组合格式为digest:username:BASE64(SHA1(password)):[permissions]
    auth与digest的区别就是:一个明文、一个密文、需要不同的访问方式

setAcl /path auth:lee:lee:cdrwa

setAcl /path digest:lee:BASE64(SHA1(lee)):cdrwa

一般auth用的不多,因为生产环境总是要加密的

addauth digest lee:lee 后都能操作指定节点的权限
4. ip:当设置为ip指定的ip地址,此时限制ip进行访问,比如ip:192.168.1.1:[permissions]
因为用的是集群,那么比如一个订单服务的ip是192.168.1.1,还有一个是192.168.1.2那么只有这两个ip可以访问这个节点,其他的比如报账服务就不能访问这个节点
5. super:代表超级管理员,拥有所有的权限,这个很危险,一般给运维或者研发经理或者CTO,所以一般不用,常用前四个

4-8 acl的构成 permission的构成

权限字符串缩写:crdwa
  1. CREATE:创建子节点,不能创建节点
  2. READ:获取节点/子节点
  3. WRITE:设置节点数据
  4. DELETE:删除子节点
  5. ADMIN:设置权限

4-9 acl的命令行 world讲解

world:anyone:crawd

设置节点的权限

4-10 acl命令行 auth讲解

auth:user:pwd:crawd

digest:userBASE64(SHA1(pwd)):crawd
addauth digest user:pwd

再给节点设置权限时,先登录,然后再给登录对象设置权限

addauth digest user:pwd

setAcl path auth:user:pwd:[permissions]
getAcl path

4-11 acl命令行 digest讲解

登录和auth一样

addauth digest imooc:imocc

setAcl path digest:imooc:(imooc的密文):[permissions]

4-11 acl命令行 ip讲解

setAcl path ip:(ip地址):[permissions]

在之后的java客户端连接中,我们再来演示

4-12 acl之super超级管理员

场景:创建一个ipd能访问的节点,在这我们使用超级管理员账号去访问该节点

创建一个ip能访问的节点

create /names/ip xxx.xxx.xxx.xxx

setAcl /names/ip ip:xxx.xxx.xxx.xxx:crawd

修改配置文件,添加超级管理员账号

vim zkServer.sh

在nohup块中添加超级管理员账号密码(密文imooc,经过sha1和base64加密得到XwEDaL3J0JQGkRQzM0DpO6zMzZs=)

“-Dzookeeper.DigestAuthenticationProvider.superDigest=imooc:XwEDaL3J0JQGkRQzM0DpO6zMzZs=”\

重启zookeeper

./zkServer.sh restart

登录超级管理员

addauth digest imooc:imooc
getAcl /names/ip

如果没有登陆,或者登录的其他账号,则都不能访问该节点

4-13 acl的常用场景

  1. 开发/测试环境分离,开发者无权操作测试库的节点,只能看
  2. 生产环境控制指定ip的服务可以访问相关节点,防止混乱,由于有些是动态ip,有可能有点不方便

4-14 zk四字命令 Four letter words

  1. zk可以通过它自身提供的简写命令来和服务器进行交互
  2. 需要使用到nc命令 ,安装yum install nc
  3. echo [commond] | nc [ip] [port]
    【stat】:查看zk的状态信息,以及是否mode
    【ruok】:查看当前zkServer是否启动,返回imok
    【dump】:列出未经处理的会话和临时节点
    【conf】:查看相关配置信息
    【cons】:展示连接到客户端的连接信息i
    【envi】:环境变量,jdk,zookeeper等
    【mntr】:监控zk的健康信息
    【wchs】:展示watch的信息
    【wchc与wchp】:session与watch及path与watch信息
    注:如果报错例如:
    ruok is not executed because it is not in the whitelist.解决方法请看https://blog.csdn.net/x763795151/article/details/80599498

注:查看zookeeper事务日志

在配置文件zoo_sample.cfg中,事务日志和快照日志,默认在dataDir中
在配置了zoo.cfg之后,事务日志和快照日志分离,事务日志在在我们配置的dataLogDir中

由于事务日志是二进制数据,因此用vi/vim不能查看得到,因此只能解码后查看

mkdir /use/log

cd /usr/local/zookeeper/lib
cp slf4j-api.1.7.25.jar zookeeper.3.5.6.jar zookeeper.jute.3.5.6.jar /usr/log

java -classpath .:slf4j-api.1.7.25.jar:zookeeper.3.5.6.jar:zookeeper.jute.3.5.6.jar org.apache.zookeeper.LogFormatter /usr/local/zookeeper/dataLogDir/version-2/log.4e

1.创建一个文件夹log保存我们所需要的jar包

2.切换到zookeeper的lib文件夹下
3.复制所需要jar包到log中
4.编写解码信息
/usr/local/zookeeper/dataLogDir/version-2/log.4e
是我们的事务日志路径

注:测试ookeeper版本为3.5.6

1、节点目录下有子节点,则父节点不能删除------父节点不能删除
2、如果节点是在/目录下且该节点没有子节点,不管有没有删除权限,任何的授权或者未授权用户都能删除该节点------根节点若没有子节点可以随便删除
3、如果该节点上一层且只能是上一层父节点,没有删除权限,则该节点不能被删除------本节点的父节点没有被删除的权限,则该节点也不能删除

5-1 zookeeper集群搭建

zk集群,主从节点,心跳机制(选举模式)

zookeeper集群搭建注意点

1.配置数据文件myid1/2/3对应server.1/2/3

2.通过./zkCli.sh -server [ip]:[port]检测集群是否配置成功

5-2 单机伪分布式集群

单机的意思是在一台服务器上创建多个zookeeper节点,ip不见端口不一

创建额外的两个zookeeper节点

cp zookeeper zookeeper01 -rf

cp zookeeper zookeeper02 -rf

修改配置文件
/usr/local/zookeeper/conf/zoo.cfg

vim /usr/local/zookeeper/conf/zoo.cfg

dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
clientPort=2181
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890

添加配置文件myid

vim /usr/local/zookeeper/conf/myid

1

/usr/local/zookeeper01/conf/zoo.cfg

vim /usr/local/zookeeper01/conf/zoo.cfg

dataDir=/usr/local/zookeeper01/dataDir
dataLogDir=/usr/local/zookeeper01/dataLogDir
clientPort=2182
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890

添加配置文件myid

vim /usr/local/zookeeper/conf/myid

2

/usr/local/zookeeper02/conf/zoo.cfg

vim /usr/local/zookeeper02/conf/zoo.cfg

dataDir=/usr/local/zookeeper02/dataDir
dataLogDir=/usr/local/zookeeper02/dataLogDir
clientPort=2183
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890

添加配置文件myid

vim /usr/local/zookeeper/conf/myid

3

节点创建配置完毕之后欧需要依次启动三个节点的zookeeper服务器

cd /usr/local/zookeeper01/bin

./zkServer.sh -server 192.168.227.128:2181
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2182
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2183

验证集群是否配置成功:

在一个zookeeper端口创建一个节点/team在另一个zookeeper端口查看是否存在这个节点/team,如果存在就代表配置成功

5-3 三台物理机(虚拟机)安装zookeeper

需要克隆三台虚拟机

将serveer的ip和端口替换即可
zoo.cfg都替换如下列属性

dataDir=/usr/local/zookeeper/dataDir

dataLogDir=/usr/local/zookeeper/dataLogDir
clientPort=2181
server.1=192.168.227.131:2888:3888
server.2=192.168.227.132:2888:3888
server.3=192.168.227.133:2888:3888

6-1 客户端与zk服务器的连接& zk会话重连机制

连不上

//zookeeper的地址public static final String zkAddress = "192.168.227.131:2181";public static void main(String[] args) throws IOException, InterruptedException, KeeperException {   ZooKeeper zk = new ZooKeeper(zkAddress, 2000, new Watcher() {              @Override            public void process(WatchedEvent watchedEvent)         {                      System.out.println("watcher事件:" + watchedEvent.getState().toString());        }    });    long sessionId = zk.getSessionId();    byte[] sessionPwd = zk.getSessionPasswd();    System.out.println("与zookeeper正在连接:" + zk.getState());    //连接过程需要时间    Thread.sleep(2000);    System.out.println("与zookeepeer连接成功:" + zk.getState());    //zk会话重连    zk = new ZooKeeper(zkAddress, 2000, new Watcher() {               @Override            public void process(WatchedEvent watchedEvent) {   }        }, sessionId, sessionPwd);    System.out.println("与zookeeper正在连接:" + zk.getState());    Thread.sleep(2000);    System.out.println("与zookeepeer重连成功:" + zk.getState());}//控制台打印与zookeeper正在连接:CONNECTINGwatcher事件:SyncConnected与zookeepeer连接成功:CONNECTEDwatcher事件:Closedzk状态:CLOSED与zookeepeer开始重连...与zookeeper正在连接:CONNECTING与zookeepeer重连成功:CONNECTED

如果连接不上zookeeper:请关闭虚拟机防火墙,再次连接

systemctl stop firewalld.service

6-2 创建节点

同步创建:zk.create(path, data, acl, CreateMode);

异步创建:zk.create(path, data, acl, CreateMode, CallBack, ctx);

acl:控制权限策略

Ids.OPEN_ACL_UNSAFE–>world:anyone:crawd
CREATOR_ALL_ACL–>auth:user:password:crawd

CreateMode:节点类型:是一个枚举

PRESISTENT:持久节点
PRESISTENT_SEQUENTIAL:持久顺序节点
EPHEMERAL:临时节点
EPHEMERAL_SEQUENTIAL:临时顺序节点

//同步创建zk.create("/java", "java".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);//异步创建zk.create("/sys_java", "sys_java".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,        CreateMode.PERSISTENT, new MyCallBack(), ctx);//执行回调函数需要时间Thread.sleep(2000);

6-3 修改节点数据

同步方式

setData(path, data, version)
异步方式
setData(path, data, version, CallBack, ctx)

6-4 删除节点

同步方式

delete(path, data, version)
异步方式
delete(path, data, version, CallBack, ctx)

6-5 CountDownLatch的介绍

线程中的计数器

分布式锁中的计数器

  1. 它是一个计数器,可以累减
  2. 多用于线程,乐意暂停也可以继续
  3. .await() .CountDown()

6-6 节点查询

//节点查询有同步查询有异步查询,在这里讨论的是同步查询,异步查询只不过有个回调函数,返回一些需要的数据,可以自己试试看//父节点查询ZooKeeperServer zooKeeperServer = new ZooKeeperServer(addressPath);//true表示再次添加watcher监听,false为不在添加byte[] data = zooKeeperServer.getZooKeeperServer().getData("/java", false, stat);String info = new String(data);System.out.print(info);//子节点查询List
nodeList = zookeeper.getZookeeperServer().getChildren("/java",false,stat);for(String nodeName : nodeList) { System.out.print(nodeName); }
上一篇:Github 12306抢票项目部署
下一篇:zookeeper:查看事务日志

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年03月21日 07时22分45秒