code: private synchronized void regAndSubscribeNodeEvent() {
  		//创建node节点
  		zkClient.createEphemeral(nodeStateParentPath + "/" + JobContext.getContext().getNodeId());
  		
  		//订阅节点信息变化
          zkClient.subscribeChildChanges(nodeStateParentPath, new IZkChildListener() {
  			@Override
  			public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
  				//
  				if(currentChilds == null || !currentChilds.contains(JobContext.getContext().getNodeId())){
  					zkClient.createEphemeral(nodeStateParentPath + "/" + JobContext.getContext().getNodeId());
  					logger.info("Nodelist is empty~ node[{}] re-join task clusters",JobContext.getContext().getNodeId());
  					return;
  				}
  				logger.info(">>nodes changed ,nodes:{}",currentChilds);
  				//分配节点
  				rebalanceJobNode(currentChilds);
  				//刷新当前可用节点
  				JobContext.getContext().refreshNodes(currentChilds);
  			}
  		});
          
          logger.info("subscribe nodes change event at path:{}",nodeStateParentPath);
          //注册命令事件
          registerCommondEvent();
          logger.info("subscribe command event at path:{}",nodeStateParentPath + "/" + JobContext.getContext().getNodeId());
          //刷新节点列表
          List<String> activeNodes = zkClient.getChildren(nodeStateParentPath);
  		JobContext.getContext().refreshNodes(activeNodes);
  		
  		logger.info("current activeNodes:{}",activeNodes);
  	}
docs: 订阅节点事件
  @return