Dubbo应用连接Zookeeper问题与解决方案

最近,遇到了一个关于Dubbo应用启动的问题,在部署应用的过程中,应用无法成功连接到ZooKeeper进行服务注册。尽管telnet端口显示正常,排除了网络问题,但问题仍然存在。

首先,查看日志获取线索分析问题。日志中有很明显的连接ZooKeeper失败的错误:

java.lang.RuntimeException: Can not create registry service-discovery-registry
Caused by: java.lang.IllegalStateException: Create zookeeper service discovery failed
Caused by: java.lang.IllegalStateException: failed to connect to zookeeper server

确认应用到ZooKeeper服务器的网络正常,telnet端口是通的。因此直接尝试再次启动应用,仍然是这个错误,并且注意到输出以下日志前有较长时间的停顿:

INFO org.apache.zookeeper.ClientCnxn: Will not attempt to authenticate using SASL (unknown error)

虽然日志级别是INFO,但是这条日志与前一条ZooKeeper相关的日志间隔了20秒。

SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。如果使用SASL身份验证,需要在客户端应用程序中配置相应的jaas.conf文件,以便能够通过SASL进行身份验证并与ZooKeeper进行安全通信。

确认不需要使用SASL身份验证,首先禁用该功能以排除干扰。在启动命令中添加以下java虚拟机选项即可:

-Dzookeeper.sasl.client=false

然而,更改配置后,虽然上述SASL未知错误消失了,但仍然连接ZooKeeper失败。

此时,再次确认了ZooKeeper的端口是通的,telnet连接非常快。

根据网上的解决方案,将连接超时时间调大,应用确实能成功连接到ZooKeeper,但应用启动时间非常长,将近1分钟。这个方案显然不是最佳选择。

再次深入查看应用启动日志,发现以下两条日志之间的间隔较长:

INFO o.a.c.f.imps.CuratorFrameworkImpl : Default schema
INFO org.apache.zookeeper.ClientCnxn : Opening socket connection to server

于是到ClientCnxn里面找原因。这两条日志是在startConnect()里面输出的。通过远程调试,发现调用InetSocketAddress的getHostName()这里等待了20秒。稍微看了一下,这个方法是调用InetAddress的getHostName()获取IP地址对应的主机名。

这个问题好解决,都是同一个局域网内的机器,在/etc/hosts中设置ZooKeeper集群各节点IP地址即可。然后再次启动应用,日志输出正常,十几秒后应用成功启动并注册到ZooKeeper。

总的来说,在解决Dubbo应用启动时遇到的ZooKeeper连接问题时,需要综合考虑多种因素,但都离不开查看日志。同时,对于日志中出现的异常信息和间隔时间较长的日志,也需要深入分析并找到根本原因,异常信息是结果,间隔较长是问题现象,通过分析现象有助于找出根本原因。

你可能感兴趣的:(Java,dubbo,zookeeper)