一.watch事件
1.为父节点设置watch事件(一次性的,借助工具可以弄成可以多次)
1.用stat为父节点设置watch事件,创建触发NodeCreated事件
WatchedEvent state:SyncConnected type:NodeCreated path:/testWatch
2.用ls为父节点设置watch事件,创建子节点触发NodeChildrenChanged事件
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testZnode
3.用ls为父节点设置watch事件,修改子节点不触发事件,要用get为它的子节点设置watch事件才行(把子节点当作父节点来看)
get /testWatch/sonnode watch
4.用stat为父节点设置watch事件,修改触发NodeDataChanged事件
WatchedEvent state:SyncConnected type:NodeDataChanged path:/testZnode
5.用stat为父节点设置watch事件,删除触发NodeDeleted事件
WatchedEvent state:SyncConnected type:NodeDeleted path:/testWatch
6.用ls为父节点设置watch事件,删除子节点触发NodeChildrenChanged事件
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testZnode
2、watch使用场景
为节点设置watch事件,当主配置(主节点上)更新时,客户端(java程序端)监听到watch事件后,就将配置更新为主节点上一样的配置,这样配置就同步了。
二.acl访问控制权限(access control permission)
1.acl构成: [scheme:id:permissions]
例如:world:anyone:cdrwa
scheme: 权限模式(world/auth/digest/id/super)
id: 用户(username:password)
permissions: 权限表达式(crdwa分别代表 创建/读取/删除/写入/管理)
2.操作
1.setAcl /testNode world:anyone:crdwa
[zk: localhost:2181(CONNECTED) 6] setAcl /testZnode/testAcl world:anyone:crda
2.getAcl /testNode
[zk: localhost:2181(CONNECTED) 8] getAcl /testZnode/testAcl
'world,'anyone
: cdra
3.设置用户权限(用户名:myname 密码:password), 提示无效(需要登陆用户)
[zk: localhost:2181(CONNECTED) 1] setAcl /testZnode/testAcl2 auth:myname:mypassword:crda
Acl is not valid : /testZnode/testAcl2
4.登陆一下
[zk: localhost:2181(CONNECTED) 0] addauth digest myname:mypassword
5.在重新设置,成功了
[zk: localhost:2181(CONNECTED) 1] setAcl /testZnode/testAcl2 auth:myname:password:crda
cZxid = 0x1900000fc6
ctime = Mon May 14 12:43:22 CST 2018
mZxid = 0x1900000fc6
mtime = Mon May 14 12:43:22 CST 2018
pZxid = 0x1900000fc6
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
6.再去改节点的内容,提示认证无效,不能修改
[zk: localhost:2181(CONNECTED) 2] set /testZnode/testAcl2 666
Authentication is not valid : /testZnode/testAcl2
7.其它模式操作类似()
world: setAcl /testZnode/testAcl2 world:anyone:crdwa
auth: setAcl /testZnode/testAcl2 auth:myname:mypassword:crda
digest: setAcl /testZnode/testAcl2 digest:myname:jd2ErFo0AbcSSSfXUZWfus8DYaM=:crda
id: setAcl /testZnode/testAcl2 ip:192.168.0.16:crdwa
super: setAcl /testZnode/testAcl2 world:anyone:crdwa
注意点:
1.auth使用明文
2.digest使用密文,但使用addauth登陆还是用明文登陆,会自动转换成密文
3.使用addauth添加用户后,就不能更改用户了
8.使用super有点特别,需要额外操作
1.修改zkServer.sh,增加super管理员
找到这行修改 nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
在${ZOO_LOG4J_PROP}"后 \前添加 "-Dzookeeper.DigestAuthenticationProvider.superDigest=myname:jd2ErFo0AbcSSSfXUZWfus8DYaM="
(这个类从源码中找到的,这里的意思是设置super用户名为myname,密码为mypassword)
2.重启zkServer.sh
3.使用场景
· 1.使用命名空间的概念(不同权限的节点是不同的空间),使用开发/测试环境分离·
· 2.使用id模在开发时控制指定ip访问指定节点,防止混乱·
三.四字命令(4个字符缩写的命令)
1.先安装nc命令
yum install nc
2.使用格式echo [commond] | nc [ip][port]
1.示例操作
1.查看zk的状态信息和mode
[root@server src]# echo stat | nc 192.168.8.84 2181
Zookeeper version: 3.4.5-1392090, built on 09/30/2012 17:52 GMT
Clients:
/192.168.8.84:43980[0](queued=0,recved=1,sent=0)
Latency min/avg/max: 0/0/9
Received: 157
Sent: 156
Connections: 1
Outstanding: 0
Zxid: 0x1900000fd6
Mode: follower
Node count: 54
2.查看是否启动
[root@server src]# echo ruok | nc 192.168.8.84 2181
imok
3.列出未经处理的会话和临时节点
[root@server src]# echo dump | nc 192.168.8.84 2181
SessionTracker dump:
org.apache.zookeeper.server.quorum.LearnerSessionTracker@3fe135c2
ephemeral nodes dump:
Sessions with Ephemerals (0):
4.查看配置
[root@server src]# echo conf | nc 192.168.8.84 2181
clientPort=2181
dataDir=/usr/local/src/zookeeper-3.4.5/data/version-2
dataLogDir=/usr/local/src/zookeeper-3.4.5/data/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=4
initLimit=10
syncLimit=5
electionAlg=3
electionPort=3888
quorumPort=2888
peerType=0
5.查看zk的健康状况
[root@itcast04 src]# echo mntr | nc 192.168.8.84 2181
zk_version 3.4.5-1392090, built on 09/30/2012 17:52 GMT
zk_avg_latency 0
zk_max_latency 9
zk_min_latency 0
zk_packets_received 161
zk_packets_sent 160
zk_num_alive_connections 1
zk_outstanding_requests 0
zk_server_state follower
zk_znode_count 54
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 1458
zk_open_file_descriptor_count 33
zk_max_file_descriptor_count 4096
四.zookeeper分布式锁思路(结合curator)
1.配置zk客户端bean(里面包含了策略),配置curatorFactorybean(将spring和curator集成在一起)
- 创建一个分布式锁类(里面维护了一个countDownLatch),配置成spring的bean
3.上面分布式锁类包含init初始化方法,getLock,releaseLock,addWatcherToLock方法
4.在init中用curator创建zk的命名空间和锁的根节点,并使用addWatcherToLock监听这个根节点
5.使用getLock方法时用curator在上面创建的根节点下创建临时节点(也就是锁,所以创建的节点名要一样,不同的业务锁以这个名称区分),如果创建不成功(其它的线程在用这把锁),就用countDownLatch.await挂起线程
6.在addWatcherToLock方法中使用PathChildrenCache监听zk节点上的事件,如果监听到节点删除事件(有线程释放了锁),判断删除的节点名是不是上面getLock时创建的节点名,如果是则调用counDownLatch.countDown()方法将前面挂起的线程放开,
7.使用releaseLock方法时删除上面的临时节点时先判断这个路径(节点)是否存在,存在就删除这个节点
8.使用这个锁时,在业务类(Service)里注入这个锁类,在进入业务方法时首先调用getLock锁住这个方法,在执行完方法返回前调用releaseLock释放掉这个锁(注意:一定要记得释放,这个业务方法中间出来异常的地方也要调用releaseLock释放掉这个锁)
网友评论