本文将关注Zookeeper中一些比较棘手的方面,主要与会话和时序相关。 虽然不影响我们开发,但当遇到这些问题时,能够有更好的理解。
访问权限在创建节点时设置,并且不会继承父节点的访问权限设置。 Zookeeper通过access control lists (ACLs)来控制访问, 一个ACL实体由schema:auth-info组成。
/**
* scheme: 验证方式
* auth: 授权信息
*/
void addAuthInfo(String scheme, byte auth[])
# 使用digest模式,用户名为amy,密码摘要为Iq0onHjzb4KyxPAp8YWOIC8zzwY=,访问控制为READ | WRITE | CREATE | DELETE | ADMIN
digest:amy:Iq0onHjzb4KyxPAp8YWOIC8zzwY=, READ | WRITE | CREATE | DELETE | ADMIN
# 对10.11.12.0 ~ 10.11.12.255仅有读权限
ip:10.11.12.0/24, READ
public class ProviderRegistry {
...
public static void initialize() {
synchronized (ProviderRegistry.class) {
if (initialized) return;
// ip认证方式
IPAuthenticationProvider ipp = new IPAuthenticationProvider();
// digest认证方式
DigestAuthenticationProvider digp = new DigestAuthenticationProvider();
authenticationProviders.put(ipp.getScheme(), ipp);
authenticationProviders.put(digp.getScheme(), digp);
Enumeration<Object> en = System.getProperties().keys();
while (en.hasMoreElements()) {
String k = (String) en.nextElement();
// 扩展的认证方式
if (k.startsWith("zookeeper.authProvider.")) {
String className = System.getProperty(k);
try {
Class<?> c = ZooKeeperServer.class.getClassLoader().loadClass(className);
AuthenticationProvider ap = (AuthenticationProvider)c.newInstance();
authenticationProviders.put(ap.getScheme(), ap);
} catch (Exception e) {
LOG.warn("Problems loading " + className,e);
}
}
}
initialized = true;
}
}
}
public interface AuthenticationProvider {
/**
* 认证方式名称
*/
String getScheme();
/**
* 该方法在Client发送验证信息后调用
* @param cnxn
* 接收验证信息的连接对象
* @param authData
* 验证信息
*/
KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte authData[]);
/**
* 验证id是否匹配对应的ACL记录的表达式id
*/
boolean matches(String id, String aclExpr);
/**
* 该Provider的验证是否用来标识节点的创建者
*/
boolean isAuthenticated();
/**
* 验证信息id是否有效
*/
boolean isValid(String id);
}
zk.sync(path, voidCb, ctx);
zk.getData(path, watcher, dataCb, ctx);
1. Client提交了执行op1的请求。 2. Client发现了ConnectionLoss发生,并尝试取消执行op1的请求。 3. 在会话过期前,Client重连上了Server。 4. Client提交了执行op2的请求。 5. op2被成功执行。 6. op1返回了ConnectionLoss。 7. Client又重新提交op2。