ZKClient使用


zkclient的使用记录

1.最近有一个需求是导出zk上的注册服务列表,zkclient做这个比较方便,所以就使用过程做一些记录

2.需求分析

本次这个需求需要实现2个功能:

a.取出所有分组下的服务列表,并计算提供者的个数,最终以  分组   接口   提供者个数这样的格式输出到表格

b.取出分组下的接口,截取包名,并计算同一分组下的同一包名的个数,最终以  分组     包名    个数这样 的格式输出到表格

3.代码实现

a.首先获得zk地址,设置session超时时间

1     /** zookeeper地址 */
2     static final String CONNECT_ADDR = "172.16.80.44:2181";
3     /** session超时时间 */
4 static final int SESSION_OUTTIME = 10000;//ms

b.获得与zk的连接

1 ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);

c.获得zk下的所有分组

1 List<String> children = zkc.getChildren("/");//  "/"代表获得zk下的根节点目录,即Dubbo的分组目录

d.对chlidren进行遍历,即对所有分组进行遍历,来获得服务的接口目录,然后对获得的接口列表进行遍历,获得所有接口名称

1  for (String group : children) {
2          List<String> interfaces = zkc.getChildren("/" + group);//这一步获得分组下的所有接口
           for (String interfaceName : interfaces) {//对接口列表进行遍历
                    System.out.println(interfaceName);
//List<String> msg = zkc.getChildren("/" + group + "/" + interfaceName + "/providers");//这样可以获得接口的提供者
           } 
3 }

 

这一部分主要介绍了如何获得zk连接,并获得列表的过程,主要是通过zkc.getChildren()实现的,通过group+interface+providers获得分组,接口,提供者等信息,providers.size()获得提供者个数

下面给出完整 的例子

4.完整例子

这个例子实现了获取接口列表,计算提供者个数,截取接口的包名等功能,最后输出到.csv文件。最后还进行了csv文件的合并

a.关于截取包名这个功能,想到了用substring这个方法,接口全路径名到接口名那出现大写字母,所以对于全路径名,截取大写字母之前的路径

 1 public static String getString(String str){
 2         int index = -1;
 3         char[] chars = str.toCharArray();
 4         if(chars!=null){
 5             for(int i=0; i<chars.length; i++){
 6                 if((chars[i] >= 'A') && (chars[i] <= 'Z')){
 7                     index = i;
 8                     break;
 9                 }
10             }
11 
12         }
13         return str.substring(0, index-1);//考虑到大写字母之前还有一个点,所以index-1返回,zk上有的分组下面没有接口,会发生Index=-2越界问题,建议排除掉这些分组
14     }

b.关于文件输出问题,采用了PrintWriter这个类

1 PrintWriter out = null;
2         try {
3             out = new PrintWriter(new BufferedWriter(new FileWriter("11.csv")));//11.csv是记录输出的位置
4             out.println("group,prefix,number");//以","分隔目录在表格里这是三个单元格的开头
              out.println(group + "," + key + "," + map.get(key));//这是具体的输出内容,分组,包名,个数

5 }catch (Exception e){
         e.printStackTrace(); 
} 

c.关于截取包名之后如何计数的问题,在获得一个分组的所有接口列表后,进行包名截取,然后new一个map,key=包名,value=相同包名重复的次数

 1
       Map<String, Integer> map = new HashMap<String, Integer>();//new HashMap用于存放包名和其在一个分组下出现的次数
       for (String interfaceName : interfaces) {//遍历接口列表
 2          try {
 3               String packageName = getString(interfaceName);//截取包名
 4               Integer times = map.get(packageName);//先从map里取值,看能不能取到值,能取到,times+1,不能取到就放入map里,times=1
 5               if (null != times) {
 6               times = times + 1;
 7               map.put(packageName, times);
 8               } else {
 9                      map.put(packageName, 1);
10               }
11          12               List<String> msg = zkc.getChildren("/" + group + "/" + interfaceName + "/providers");
13               for (String s:msg) {
14                      System.out.println(s);
15                     }
16 
17 18             } catch (Exception e) {
19                        e.printStackTrace();
20                         }
21                     }//循环结束
22           System.out.println(map); //这个map存放着对象的hascode值和重复次数
23           Set<String> keys = map.keySet();//key值的集合,就是对象的 hascode的值
24           for (String key : keys) {
25                   out.println(group + "," + key + "," + map.get(key));//这里输出,分组,包名,同一包名的次数
26                 }

d.由于是要实现2个需求,所以最终文件输入到了2个csv文件中,现在需要将2个csv整合到一起,将2个csv文件放到同一个文件夹中,新建一个excel文件,打开excel文件,在sheet上右击,选择检查代码

 1 Private Sub copy_csvfile_to_excel()
 2 
 3 Dim MyPath$, myFile$, AK As Workbook
 4    Application.ScreenUpdating = False
 5    MyPath = ThisWorkbook.Path & "\"
 6    myFile = Dir(MyPath & "*.csv")
 7    Do While myFile <> ""
 8       If myFile <> ThisWorkbook.Name Then
 9          Set AK = Workbooks.Open(MyPath & myFile)
10          AK.Sheets(1).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
11          Workbooks(myFile).Close
12          End If
13       myFile = Dir
14       Set AK = Nothing
15     Loop
16    Application.ScreenUpdating = True
17    ActiveWorkbook.Save
18    MsgBox "汇总完成,请查看!", 64, "提示"
19 End Sub

e.下面是这个例子的完整代码

 

 1 package com.alibaba.dubbo.zkc.zkc;
 2 
 3 import com.alibaba.dubbo.common.utils.StringUtils;
 4 import org.I0Itec.zkclient.ZkClient;
 5 import org.I0Itec.zkclient.ZkConnection;
 6 
 7 import java.io.BufferedWriter;
 8 import java.io.FileWriter;
 9 import java.io.IOException;
10 import java.io.PrintWriter;
11 import java.util.*;
12 
13 
14 /**
15 
16 
17 
18  */
19 public class ZKClientBase {
20     /** zookeeper地址 */
21     static final String CONNECT_ADDR = "127.0.0.1:2181";//zk地址选择自己需要的,多个zk以逗号分隔,"192.168.1.171:2181,192.168.1.172:2181,192.168.1.173:2181"
22     /** session超时时间 */
23     static final int SESSION_OUTTIME = 10000;//ms
24 
25     public static String getString(String str){
26         int index = -1;
27         char[] chars = str.toCharArray();
28         if(chars!=null){
29             for(int i=0; i<chars.length; i++){
30                 if((chars[i] >= 'A') && (chars[i] <= 'Z')){
31                     index = i;
32                     break;
33                 }
34             }
35 
36         }
37         return str.substring(0, index-1);
38     }
39 
40 
41 
42     public static void main(String[] args) throws Exception {
43         ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);
44 
45         PrintWriter out = null;
46         try {
47             out = new PrintWriter(new BufferedWriter(new FileWriter("packageNumber44.csv")));
48             out.println("group,prefix,number");
49             List<String> children = zkc.getChildren("/");
50             Map<String, Integer> map = new HashMap<String, Integer>();
51             for (String group : children) {
52                 if (!group.equals("BSSTask") && !group.equals("zookeeper") && !group.equals("ocs_root")&&!group.equals("ZMQ")) {
53                     List<String> interfaces = zkc.getChildren("/" + group);
54                     //System.out.println(group);
55                     for (String interfaceName : interfaces) {
56                         try {
57                             String packageName = getString(interfaceName);
58                             Integer times = map.get(packageName);
59                             if (null != times) {
60                                 times = times + 1;
61                                 map.put(packageName, times);
62                             } else {
63                                 map.put(packageName, 1);
64                             }
65                             if (interfaceName.equals("com.ztesoft.inf.hsf.service.ReceiveHBResult")||interfaceName.equals("com.ztesoft.bss.svcability")){
66                                 List<String> msg = zkc.getChildren("/" + group + "/" + interfaceName + "/providers");
67                                 for (String s:msg) {
68                                     System.out.println(s);
69                                 }
70 
71                             }
72                         } catch (Exception e) {
73                             e.printStackTrace();
74                         }
75                     }//循环结束
76                     System.out.println(map); //这个map存放着对象的hascode值和重复次数
77                     Set<String> keys = map.keySet();//key值的集合,就是对象的 hascode的值
78                     for (String key : keys) {
79                         out.println(group + "," + key + "," + map.get(key));
80                     }
81                 }
82             }
83 
84         } catch (IOException e) {
85             e.printStackTrace();
86         } finally {
87             if (out != null) {
88                 out.close();
89             }
90         }
91 
92 
93     }
94 }

5.简单总结

网上的例子大多是自己在zk上增加和删除节点,监听节点的变化等,本次我的需求是自己去zk上获取数据,参考了网上给出的例子,实现了自己的需求,第一次写随笔,很多细节处理的都不好,如带来困扰,敬请谅解

6.参考链接

https://blog.csdn.net/t1dmzks/article/details/78440717   //zkclient用法

https://blog.csdn.net/u011089523/article/details/53421333?locationNum=14&fps=1     //将多个csv文件写入一个excel的不同sheet中

https://www.cnblogs.com/wang-zai/p/7799778.html       //截取第一个大写字母前的字符串

https://blog.csdn.net/jie1991liu/article/details/50424304  //计算一个list中某一个元素重复的参数

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM