Zookeeper断网重连事件回调源码分析

文章详细分析了使用Curator作为zk客户端时,断网后重连如何触发ConnectionStateListener的RECONNECTED事件,涉及源码追踪和事件处理机制。

“不积跬步,无以至千里。”

背景

  • 确定使用Curator作为zk客户端的情况下,断网[发生SUSPENDED | LOST事件]重连后每次都会回调org.apache.curator.framework.state.ConnectionStateListener#stateChanged方法,且事件类型为org.apache.curator.framework.state.ConnectionState#RECONNECTED
  • 部署zookeeper的版本为最新稳定版3.8.3,curator-recipes相关依赖的版本为5.5.0

源码分析过程

  • 首先需要构建一个CuratorFramework对象,并基于这个CuratorFramework对象创建一个用于实现Leader选举功能的LeaderSelector,并将它启动

    public static final String leaderSelectorPath = "/source-code-analyse/reconnect";
    public static void main(String[] args) throws InterruptedException {
         
         
         CuratorFramework curatorFramework = newCuratorFramework();
         LeaderSelectorListener leaderSelectorListener = new LeaderSelectorListener() {
         
         
             @Override
             public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) {
         
         
                 System.out.println("Thread " + Thread.currentThread().getName() + " Connection state changed : " + connectionState);
             }
    
             @Override
             public void takeLeadership(CuratorFramework curatorFramework) throws Exception {
         
         
                 System.out.println("Thread " + Thread.currentThread().getName() + " get the leader.");
                 TimeUnit.SECONDS.sleep(20);
             }
         };
         LeaderSelector leaderSelector = new LeaderSelector(curatorFramework, leaderSelectorPath, leaderSelectorListener);
         leaderSelector.start();
         TimeUnit.SECONDS.sleep(100);
         leaderSelector.close();
         curatorFramework.close();
         System.out.println("Test completed.");
     }
    
      public static CuratorFramework newCuratorFramework() {
         
         
         CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
                 .connectString("192.168.0.104:2181")
                 .sessionTimeoutMs(30000)
                 .connectionTimeoutMs(6000)
                 .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                 .threadFactory(ThreadUtils.newThreadFactory("ReconnectionTestThread")).build();
         curatorFramework.start();
         return curatorFramework;
     }
    
  • 由于LeaderSelector的功能实现需要基于CuratorFramework,于是应该先看看CuratorFramework的start方法,直接看实现类CuratorFrameworkImpl

    @Override
    public void start()
    {
         
         
      log.info("Starting");
      if ( !state.compareAndSet(CuratorFrameworkState.LATENT, CuratorFrameworkState.STARTED) )
      {
         
         
        throw new IllegalStateException("Cannot be started more than once");
      }
      try
      {
         
         
        connectionStateManager.start();
        //省略代码
    
  • 发现CuratorFrameworkImpl内部维护了一个与连接状态管理器,start方法中会启动它

  • ConnectionStateManager的start方法中,会向线程池提交一个任务,去调用processEvents方法

    public void start()
    {
         
         
      Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once");
      service.submit
        (
        new Callable<Object>()
        {
         
         
          @Override
          public Object call() throws Exception
          {
         
         
            processEvents();
            return null;
          }
        }
      );
    }
    
  • processEvents方法里面核心的内容就是,从eventQueue的一个阻塞队列中不断调用poll方法获取ConnectionState对象,因为处在一个while循环中,只要当前连接状态正常,就会一直去poll

    private void processEvents()
     {
         
         
         while ( state.get() == State.STARTED )
         {
         
         
             try
             {
         
         
                 int useSessionTimeoutMs = getUseSessionTimeoutMs();
                 long elapsedMs = startOfSuspendedEpoch == 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值