依据百度后果,揣测问题可能是,当应用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,多台可能就不行了。