Zookeeper

Zookeeper客户端使用:

  1. 使用DefaultZookeeperFactory创建默认的Zookeeper;
DefaultZookeeperFactory factory = new DefaultZookeeperFactory();
factory.newZooKeeper(connectString, sessionTimeout, null, false);

    2. 直接使用Zookeeper的构造函数;

ZooKeeper zookeeper = new ZooKeeper(connectString, sessionTimeout, (event)->{}, clientConfig);

 如果所有采用默认的配置,在创建Zookeeper后建立连接时,Zookeeper的SendThread在建立连接时,startConnect()函数,先判断是否采用SASL连接,默认情况下回使用SASL连接,即创建ZooKeeperSaslClient对象。如果未配置SASL,此过程会阻塞正常与Zookeeper的连接创建,导致Zookeeper对象创建后不能立即建立与Zookeeper的连接,因此为了加快建立与Zookeeper的连接,需要将相关参数修改。

ZKClientConfig clientConfig = new ZKClientConfig();
clientConfig.setProperty("zookeeper.sasl.client", "false");
ZooKeeper zooKeeper =new ZooKeeper(connectString, sessionTimeout, (event)->{}, clientConfig);

    ClientCnxn类中SendThread的startConnect方法:

   private void startConnect(InetSocketAddress addr) throws IOException {
            // initializing it for new connection
            saslLoginFailed = false;
            if (!isFirstConnect) {
                try {
                    Thread.sleep(r.nextInt(1000));
                } catch (InterruptedException e) {
                    LOG.warn("Unexpected exception", e);
                }
            }
            state = States.CONNECTING;

            String hostPort = addr.getHostString() + ":" + addr.getPort();
            MDC.put("myid", hostPort);
            setName(getName().replaceAll("\\(.*\\)", "(" + hostPort + ")"));
            if (clientConfig.isSaslClientEnabled()) {
                try {
                    if (zooKeeperSaslClient != null) {
                        zooKeeperSaslClient.shutdown();
                    }
                    zooKeeperSaslClient = new ZooKeeperSaslClient(SaslServerPrincipal.getServerPrincipal(addr, clientConfig), clientConfig);
                } catch (LoginException e) {
                    // An authentication error occurred when the SASL client tried to initialize:
                    // for Kerberos this means that the client failed to authenticate with the KDC.
                    // This is different from an authentication error that occurs during communication
                    // with the Zookeeper server, which is handled below.
                    LOG.warn(
                        "SASL configuration failed. "
                            + "Will continue connection to Zookeeper server without "
                            + "SASL authentication, if Zookeeper server allows it.", e);
                    eventThread.queueEvent(new WatchedEvent(Watcher.Event.EventType.None, Watcher.Event.KeeperState.AuthFailed, null));
                    saslLoginFailed = true;
                }
            }
            logStartConnect(addr);

            clientCnxnSocket.connect(addr);
        }

对比zoookeeper3.4.X版本与3.5.X版本:

3.5.X版本:

if (clientConfig.isSaslClientEnabled()) {
    try {
        if (zooKeeperSaslClient != null) {
            zooKeeperSaslClient.shutdown();
        }
        zooKeeperSaslClient = new ZooKeeperSaslClient(getServerPrincipal(addr), clientConfig);
    } catch (LoginException e) {



private String getServerPrincipal(InetSocketAddress addr) {
     String principalUserName =    clientConfig.getProperty(ZKClientConfig.ZK_SASL_CLIENT_USERNAME,
                    ZKClientConfig.ZK_SASL_CLIENT_USERNAME_DEFAULT);
   String serverPrincipal = principalUserName + "/" + addr.getHostString();
 return serverPrincipal;
}

3.4.X版本:

if (ZooKeeperSaslClient.isEnabled()) {
    try {
        zooKeeperSaslClient = new ZooKeeperSaslClient(SaslServerPrincipal.getServerPrincipal(addr));
    } catch (LoginException e) {
        // An authentication error occurred when the SASL client tried to initialize:
        // for Kerberos this means that the client failed to authenticate with the KDC.
        // This is different from an authentication error that occurs during communication
        // with the Zookeeper server, which is handled below.
        LOG.warn("SASL configuration failed: " + e + " Will continue connection to Zookeeper server without "
          + "SASL authentication, if Zookeeper server allows it.");
        eventThread.queueEvent(new WatchedEvent(
          Watcher.Event.EventType.None,
          Watcher.Event.KeeperState.AuthFailed, null));
        saslLoginFailed = true;
    }
}
  static String getServerPrincipal(WrapperInetSocketAddress addr) {
        String principalUserName = System.getProperty(ZK_SASL_CLIENT_USERNAME, "zookeeper");
        String hostName = addr.getHostName();

        boolean canonicalize = true;
        String canonicalizeText = System.getProperty(ZK_SASL_CLIENT_CANONICALIZE_HOSTNAME, "true");
        try {
            canonicalize = Boolean.parseBoolean(canonicalizeText);
        } catch (IllegalArgumentException ea) {
            LOG.warn("Could not parse config {} \"{}\" into a boolean using default {}",
                ZK_SASL_CLIENT_CANONICALIZE_HOSTNAME, canonicalizeText, canonicalize);
        }

        if (canonicalize) {
            WrapperInetAddress ia = addr.getAddress();
            if (ia == null) {
                throw new IllegalArgumentException("Unable to canonicalize address " + addr + " because it's not resolvable");
            }

            String canonicalHostName = ia.getCanonicalHostName();
            //avoid using literal IP address when security check fails
            if (!canonicalHostName.equals(ia.getHostAddress())) {
                hostName = canonicalHostName;
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("Canonicalized address to {}", hostName);
            }
        }
        String serverPrincipal = principalUserName + "/" + hostName;
        return serverPrincipal;
    }

两个版本的主要区别在与:3.4.X版本会去解析域名,导致创建了Zookeeper时,延迟创建连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值