[toc]
命令行
- ls / ls2
- delete
- set
- get
- stat
节点持久类型
1 | PERSISTENT // 持久节点,一旦创建成功不会被删除,除非客户端主动发起删除请求 |
ACL
zookeeper 的 acl 通过 [ scheme : id : permissions ] 来构成权限列表。
- scheme:代表采用的某种权限机制,包括 world、auth、digest、ip、super 几种。
- id:代表允许访问的用户。
- permissions:权限组合字符串,由 cdrwa 组成,其中每个字母代表支持不同权限
- 创建权限 create (c)
- 删除权限 delete (d)
- 读权限 read (r)
- 写权限 write (w)
- 管理权限admin (a)。
Acl 命令
- setAcl
- getAcl
world 实例
1 | $ getAcl /runoob/child |
直接操作 world:anyone
即可。即默认节点权限。
auth 实例
auth 实例用于授权。
授权需要新建用户
1 | addauth digest user1:123456 # 创建用户 |
这里 digest 相当于是创建也相当于手授权。这时候退出终端,再访问 /runoob/child
就会返回 No Auth 报错
1 | [zk: localhost:2181(CONNECTED) 0] get /runoob/child |
再通过 addauth digest user1:123456
验证之后就可以正常访问。
digest 实例
在 auth 对 Node 进行了授权,授权需要用户的密码。
但是如果是管理员,能否在不知道用户的密码的前提下对 Node 进行授权?
答案是可以的。
这里注意 getAcl /runoob/child
返回了
1 | 'digest,'user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s= |
使用 digest 进行授权:
1 | create /runoob/child01 runoob |
区别于 auth 需要用户的密码,digest 授权更适合管理员进行操作。在已知用户密码加密后的内容之后,也可以对其他的 node 进行授权。
IP 实例
利用 ip 进行授权
1 | create /runoob/ip 0 |
用 zk 实现非公平锁
本质就是依赖 zk Node 只能被同时创建一次来实现。
- 创建 Node
- 成功
- 失败
- 监听 NodeDeleted 事件
- 继续创建 Node
- 成功
- 失败
- 继续监听…
- 继续创建 Node
- 监听 NodeDeleted 事件
EPHEMERAL 临时节点可以避免客户端断开链接但是未删除造成的死锁。
临时节点在链接断开之后自动删除节点
用 zk 实现公平锁
依赖 EPHEMERAL_SEQUENTIAL 的特性。
所有竞争者都去 Node 上创建,并且获得顺序的唯一 id。
创建完就去获得 Node 列表中第一个 Node。如果 Node 相同说明获得锁,反之说明获得锁失败。
如果失败,就去监听当前自己获得的节点的上一个。这样一旦前者被删除了,说明自己也就可以了。
这里有个情况是,如果前者因为其他原因被删除,比如说,链接断开?
那就重复去查询列表第一个 Node,如果自己不是第一个,那就监听自己当前的前一个节点。
curator-recipes
1 | <dependency> |
1 | RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); |
InterProcessMultiLock
可以同时对几个路径加锁,释放也是同时的InterProcessMutex
可重入排他锁InterProcessReadWriteLock
读写锁InterProcessSemaphoreMutex
不可重入排他锁
Wathcer
研究的是 Java SDK 里的方法
注册 watcher 有三种方式:
- getData
- exists
- getChildren
而通过源码查看了 EventType 有 8 种:
1 | None(-1), |
watcher 对象相当于一个监听者,可以通过在 client 只设置一个通用 watcher 的办法,然后通过类似
1 | client.exists("/", true); |
的办法,把 watcher 绑定到对应的路径和方法。
除了需要的 EventType , None 类型的事件也会被监听到,所以需要过滤。
除了 None 之外,其他类型的 EventType 只会在设置后被监听到一次,所以在处理完事件之后,需要重新进行设置。
Persistent Recursive Watcher
A managed persistent persistent watcher. The watch will be managed such that it stays set through connection lapses, etc.
从定义上来看,即使与 zk 断开,依然保持链接。
客户端发送请求给服务端是通过 TCP 长连接建立网络通道,底层默认是通过 java 的 NIO 方式,也可以配置 netty 实现方式。
默认监听路径里所有的事件。
1 | client.addWatch("/", watcher, AddWatchMode.PERSISTENT); // 添加监听 |