图中权限部分(蓝色字体)之前的文章直接省略跳过了,没有进行解释,今天我们就好好讲讲这个权限字段。
从图上也能看到权限这个字段是直接以数字(long 类型,64 位的整型数字)的方式保存在服务端的节点中的,而 -1 是一个特殊的值代表不进行权限的校验对应的就是之前的 OPEN_ACL_UNSAFE 常量。
而 ACL 权限无论是创建节点时提供的(ACL 参数是一个 List),还是通过 addAuth 方法提供的(这个方法可以被调用多次),这两种设计都表示一个客户端是可以拥有多种权限的,比如:多个用户名密码,多个 IP 地址等等。
ACL 我之前讲过是由 3 个部分组成的,即 scheme:id:perms 为了简洁的表示我会在之后使用该形式去表示一个 ACL。
服务端会使用两个哈希表把目前接收到的 ACL 列表和其对应的数字双向的关系保存起来,类似这样(图中的 ACL 取值是我随意编造的):
ZK 服务端会维护一个从 1 开始的数字,收到一个新的 ACL 会同时放入这两个哈希表(源码中对应的就是两个 Map,一个是 Map<List<ACL>, Long>,一个是 Map<Long, List<ACL>>),除了这两个哈希表以外,ZK 服务端还为每一个客户端都维护了一个会话中的权限信息,该权限信息就是客户端通过 addAuth 添加的,但是这个客户端的权限信息只保存了 scheme:id 部分,所以结合以下三个信息就可以对客户端的本次操作进行权限校验了:
两个哈希表表示的节点的信息 scheme:id:perms,可以有多个
客户端会话上下文中的权限信息仅 id:perms ,可以有多个
本次操作对应的权限要求,即 3.3 表格中列出的所需权限
校验的流程如下:
这里额外提一下,校验器是可以自定义的,用户可以自定义自己的 scheme 以及自己的校验逻辑,需要在服务端的环境变量中配置以 zookeeper.authProvider. 开头的配置,对应的值则对应一个 class 类全路径,这个类必须实现 org.apache.zookeeper.server.auth.AuthenticationProvider 接口,而且这个类必须能被 ZK 服务端加载到,这样就可以解析自定义的 scheme 控制整个校验逻辑了,这个功能比较高级,我也没用过,大家就当补充知识了解下~
今天我们了解了 Follower 和 Observer 是如何同 Leader 进行数据同步的,以及 ZK 提供的权限管理 ACL 究竟是怎么回事,下一篇我们将聊聊 ZK 的 session 管理,客户端和服务端之间是怎么保持会话的,以及服务端不同节点之间的心跳又是怎么保持的?
最后给文章点个赞吧~什么?你说不想点?
老规矩,如果你有任何对文章中的疑问也可以是建议或者是对 ZK 原理部分的疑问,欢迎来仓库中提 issue 给我们,或者来语雀话题讨论。
地址:https://www.yuque.com/kaixin1002/yla8hz