【zookeeper】org.apache.zookeeper.KeeperException$Connection: KeeperErrorCode = ConnectionLoss for /..

private int sessionTimeout = 2000;
@Test
public void init() throws IOException {
    zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
        @Override
        public void process(WatchedEvent watchedEvent) {
//...
        }
    });
}

本来单独测试创建连接时一帆风顺,此时的超时时间还是设置为2000ms的。

后面开始添加新的节点以后创建方法报错:

org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /目标创建节点名称

百度很久没有解决方案,最后找到原来是下面这个原因。

问题就出在sessionTimeout超时时间身上,因为时间不够用,而且最根本的原因是:原因1

连接客户端的超时时间(SessionTimeout)起码要大于原来zookeeper服务端设置的延迟时间(tickTime*initLimit)

这里首先要回顾一下zookeeper的配置文件conf/zoo.cfg文件中的参数(节选文件部分): 

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
# dataDir=/tmp/zookeeper
dataDir=/opt/module/zookeeper-3.5.7/zkData
# the port at which the clients will connect
clientPort=2181

tickTime:通信心跳时间,ZooKeeper服务器与客户端心跳时间(单位:毫秒)

initLimit:初次通信时限,LF(Leader,Follower)初始连接时能容忍的最多心跳数(tickTime的个数)

syncLimit:同步通信时限,LF通信时间超过syncLimit*tickTime,L认为F已死亡,并从服务器列表中删除F

dataDir:保存Zookeeper中数据的位置

clientPort:服务器端统一使用的端口号

        因为此处tickTime为2000,initLimit为10,因此LF初次连接时的超时时间应起码大于延迟时间tickTime*initLimit的值否则会因为超时而连接失败

另附报错案例完整代码如下:

public class zkClient {

    private ZooKeeper zkClient;
    private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private int sessionTimeout = 200000;

    // 初始化是初始化ZooKeeper对象,必须要先创建,再进行创建节点,否则报空指针异常
    @Before
    public void init() throws IOException {
        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
//...
            }
        });
    }

    @Test
    public void create() throws InterruptedException, KeeperException {
        String nodeCreated = zkClient.create("/atguigu", "shuaige".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }
}

!第二天遇到同样问题更新:

控制台console出现以下错误提醒信息:

[INFO]... Socket error occurred: ip/ip:2181: Connection timed out: no further information

        进入服务器端查看,三台主机均正常连接2181端口,启动成功。但是服务器无法连接到客户端,问题可能出在:

        首先,我发现起床懵了没记得开虚拟机并开启zk集群(好想打自己。。)原因2,重新开启后仍然连不上,然后发现是因为(上面那个报错)主机的映射名字要和zookeeper的配置文件里的名字一样,要么就是ip地址,要么就只能用主机的映射名。原因3

如果各台主机名都为localhost,则默认是ip地址了。上文我的hadoop102/3/4都是映射名,如图:

        这样,跟昨天的情况报红字错误(见标题)是一样的,因此总结可以尝试的方向都在上文中红字标明了。

可能还需要关闭防火墙:原因4

# 暂时关闭防火墙

systemctl stop firewalld
service iptables stop

        前面的都试过了以后我才找到了一个办法解决,就是可能原因是我上一次关闭集群的时候很马虎,暴力导致zk没有正常关闭原因5。此时需要找到配置文件conf/zoo.cfg中的dataDir属性设置的值,默认值为/tmp,可见是保存zk临时数据的地方,进入该文件夹下,可以看到一个名为zookeeper_service.pid的文件,删除它:

rm -rf zookeeper_service.pid

再重新启动,成功连接。其他原因暂时还没有遇到,遇到了再补充吧。 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值