起因
最近在做多租户改造,租户使用的配置项都要放到zk上(如数据库配置、redis配置、阿里oss配置、每个租户的域名配置等),每个子系统去zk读取配置。当配置信息改变时,通过zk的watch机制,给子系统发消息,子系统接收到消息之后,再去做相应的处理(如:租户1的数据库配置变了,就重新创建数据库连接池)。
图1:系统关系逻辑及问题描述
问题描述:
主要是只读的那些zkClient,不用账号密码,就能读(r)到zk上的数据。而不是给子系统分配账号密码。
子系统访问zk的时候,是不能带账号密码的。
如果用digest 给子系统分配统一的一个账号密码,在代码的层面是可以实现的。
但是老大要求,子系统访问zk的时候,不能带着密码。而且,只能有读(r)权限。
思路
注:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限
使用命令看一下world的权限是cdrwa(也就是anyone拥有所有权限)
所以,突然想到,能不能把world身份认证方式的默认权限设置成r,而admin的账号分配给crdwa权限。
于是使用代码:
public void set(String path, String data) {
createPathIfNotExists(path);
zkClient.writeData(path, data);
}
/**
* 如果path不存在,则创建。
*
* @param path
*/
private void createPathIfNotExists(String path) {
String id = null;
try {
id = generateDigest("admin:admin"); // admin用户的账号:密码
} catch (NoSuchAlgorithmException e) {
throw new RRException("zk生成idPassword失败。zkPassword=" + zkPassword + ",zkPassword=" + zkPassword);
}
// 创建znode时,同时设置Acl权限:
List<ACL> acl = new ArrayList<>();
acl.add(new ACL(ZooDefs.Perms.ALL, new Id("digest", id)));
acl.add(new ACL(ZooDefs.Perms.READ, new Id("world", "anyone")));
createPersistentIfNotExists(path, acl);
}
private void createPersistentIfNotExists(String path, List<ACL> acl) {
if (!zkClient.exists(path)) {
zkClient.createPersistent(path, true, acl);
}
}
这样,world默认的权限就改为了readOnly的了:
参考
ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表
然而,ACL毕竟仅仅是访问控制,并非完善的权限管理,通过这种方式做多集群隔离,还有很多局限性:
(1)ACL并无递归机制,任何一个znode创建后,都需要单独设置ACL,无法继承父节点的ACL设置。
(2)除了ip这种scheme,digest和auth的使用对用户都不是透明的,这也给使用带来了很大的成本,很多依赖zookeeper的开源框架也没有加入对ACL的支持,例如hbase,storm
2. session的超时问题:
ZKClient框架里会经常看见一些while语句,是由这些while语句完成的,比如ZkClient.retryUntilConnected方法
(感谢紫川的反馈,此条可能存在描述性问题。经校对:ZkClient貌似还是有对Session Expired 处理的,在ZkClient.processStateChanged方法中。虽然能重新连接,但是连接上是一个新的 session,原有创建的ephemeral znode(即临时节点)和watch会被删除,程序上你可能需要处理这个问题。欢迎大家提出意见,万分感谢)
对上面引用的补充:zkClient重新连接之后,还会把通过org.I0Itec.zkclient.ZkClient#addAuthInfo方法设置的权限信息给删掉。也需要自己去处理这个问题。详情:
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /nb-conf
来源:oschina
链接:https://my.oschina.net/u/2475326/blog/1814143