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