关于java:java客户端连接Zookeeper服务器慢

4次阅读

共计 1550 个字符,预计需要花费 4 分钟才能阅读完成。

依据百度后果,揣测问题可能是,当应用 ip 创立 ZooKeeper 对象时,如果 host 中没有 ip 到主机名的映射,ZooKeeper 创立过程中会调用 ZooInetAddress.getHostName() 这个办法从网络中获取主机名,这里消耗工夫太长所致。通过调试定位到 SaslServerPrincipal 类的

    static String getServerPrincipal(WrapperInetSocketAddress addr, ZKClientConfig clientConfig) {String configuredServerPrincipal = clientConfig.getProperty(ZKClientConfig.ZOOKEEPER_SERVER_PRINCIPAL);
        if (configuredServerPrincipal != null) {
            // If server principal is already configured then return it
            return configuredServerPrincipal;
        }
        String principalUserName = clientConfig.getProperty(
            ZKClientConfig.ZK_SASL_CLIENT_USERNAME,
            ZKClientConfig.ZK_SASL_CLIENT_USERNAME_DEFAULT);
        String hostName = addr.getHostName();
        ......

        if (canonicalize) {WrapperInetAddress ia = addr.getAddress();
            ......
            String canonicalHostName = ia.getCanonicalHostName();
            //avoid using literal IP address when security check fails
            if (!canonicalHostName.equals(ia.getHostAddress())) {hostName = canonicalHostName;}

        }
        String serverPrincipal = principalUserName + "/" + hostName;
        return serverPrincipal;
    }

解决耗时长问题 一个形式就是改 host 文件,增加 ip 到域名的映射,但查看上述函数能够发现,如果 configuredServerPrincipal 不为 null,则不会执行 String hostName = addr.getHostName(); 也就能够绕过耗时长的问题。
所以在创立 ZooKeeper 时,传入 ZKClientConfig 对象,并配置一个属性,代码如下

            String connectString="117.76.191.159";
            ZKClientConfig zkClientConfig = new ZKClientConfig();
            zkClientConfig.setProperty(ZKClientConfig.ZOOKEEPER_SERVER_PRINCIPAL,"zookeeper/"+connectString);
            zooKeeper = new ZooKeeper(connectString, timeout, new Watcher() {
                @Override
                public void process(WatchedEvent event) {}},false,new StaticHostProvider(new ConnectStringParser(connectString).getServerAddresses()),zkClientConfig);

该办法适宜单台 Zookeeper,多台可能就不行了。

正文完
 0