zookeeper客户端Curator

Curator是zookeeper的客户端之一,以下通过模拟实现dubbo-Admin的功能来介绍Curator.

我们都知道,dubbo一般都使用zk来做目录服务,dubbo在zk上注册的根节点就“/dubbo”,所以我们通过节点查询来实现查询和监控服务状态。

1.引入curator

<dependency>  
	<groupId>org.apache.curator</groupId>  
	<artifactId>curator-recipes</artifactId>  
	<version>2.8.0</version>
</dependency>  

 2.构造zk的链接

package com.zk;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;

public class ZkClientFactory {
	 private static CuratorFramework client;
	 //构造全局的zk链接对象。当然也可以通过配置增加更多的参数
	 public static CuratorFramework  getInstance(String url){
		 if(null == client){
			 synchronized(ZkClientFactory.class){
				 if(null == client){
					 CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();  
				        client = builder.connectString(url) 
				        		.sessionTimeoutMs(3000)  
				                .connectionTimeoutMs(3000)  
				                .canBeReadOnly(false)  
				                .retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE))  
				                .namespace(null)  
				                .defaultData(null)  
				                .build();  
				        client.start();
				 }
			 }
		 }
		 return client;
	 }
}

 3.查询dubbo服务并打印

package com.zk;

import java.net.URLDecoder;
import java.util.List;

import org.apache.curator.framework.CuratorFramework;


public class DubboAdmin {
    private static final String ZK_ADDRESS = "127.0.0.1:2182";
    
    private static String serverName = "MyService";
    
    private static CuratorFramework client = ZkClientFactory.getInstance(ZK_ADDRESS);

    public static void main(String[] args) throws Exception {
    	
    	
    	List<String> services =  client.getChildren().forPath("/dubbo");
    	if(null == services || services.isEmpty()){
    		System.out.println("No service in Zk...");
    		System.exit(1);
    	}
    	System.out.println("Search Service ["+serverName+"] start...");
    	for(String str : services){
    		if(str.contains(serverName)){
    			printDetail(str);
    		}
    	}
    	System.out.println("Search Service ["+serverName+"] end." );
    }
    //打印单个服务节点信息
    private static void printDetail(String str) throws Exception{
    	System.out.println("==================================");
    	System.out.println("CurrentNode is:"+ str);
    	List<String> children = client.getChildren().forPath("/dubbo/"+str);
    	for(String child :children){
    		List<String> nodes = client.getChildren().forPath("/dubbo/"+str+"/"+child);
    		System.out.println("  NodeName:"+child);
    		for(String node :nodes){
    			System.out.println("   "+URLDecoder.decode(node));
    		}
    	}
    }
}

 4.打印结果   

   Search Service [CouponService] start...

==================================

CurrentNode is:com.service.MyService

  NodeName:consumers

  NodeName:routers

  NodeName:providers

   dubbo://192.168.62.85:20882/com......

   dubbo://192.168.62.85:23333/com......

  NodeName:configurators

==================================

存在的疑问:

  client.start();这个方法调后,会起线程去连zk,不管是否连接成功,client的状态都已经是started.无法判断连接状态。如果连接未成功,执行任何操作都会被阻塞。那怎么在应用启动时判断是否连接成功?

猜你喜欢

转载自chenqunhui.iteye.com/blog/2379627