zookeeper 实现一个简单的服务注册与发现(C++) 二:注册

2021-01-02 04:29

阅读:597

标签:tor   https   fine   pre   clu   ini   tostring   多个   bin   

git:git@github.com:ccx19930930/services_register_and_discovery.git

参考链接:https://www.cnblogs.com/haippy/archive/2013/02/21/2920280.html

 

base_class.h

  1 #ifndef _BASE_CLASS_H_
  2 #define _BASE_CLASS_H_
  3 
  4 #include "zk_define.h"
  5 
  6 #include string>
  7 #include   8 
  9 #include  10 
 11 using namespace std;
 12 
 13 class CUnCopyable 
 14 {
 15 protected:
 16     CUnCopyable() {}
 17     ~CUnCopyable() {}
 18 private:
 19     CUnCopyable(const CUnCopyable&);
 20     CUnCopyable& operator=(const CUnCopyable&);
 21 };
 22 
 23 class CNodeInfo
 24 {
 25 public:
 26     CNodeInfo() { Reset(); }
 27     ~CNodeInfo() {}
 28 public:
 29     void Reset()
 30     {
 31         m_ip = "";
 32         m_port = "";
 33         m_zk_path = "";
 34         m_module_name = "";
 35         m_module_id = "";
 36         m_module_idx = "";
 37     }
 38 
 39     string ToString()
 40     {
 41         stringstream oss;
 42         oss.str("");
 43         auto set_val = [&oss](const string& key, const string& value)
 44         {
 45             oss "[" "] ";
 46         };
 47 
 48         set_val("IP", m_ip);
 49         set_val("PORT", m_port);
 50         set_val("ZK_PATH", m_zk_path);
 51         set_val("MODULE_NAME", m_module_name);
 52         set_val("MODULE_ID", m_module_id);
 53         set_val("MODULE_IDX", m_module_idx);
 54 
 55         return oss.str();
 56     }
 57 
 58     void FromString(const string& info)
 59     {
 60         auto get_val = [info](string key)->string
 61         {
 62             int idx;
 63             string key1 = key + "[";
 64             string key2 = "]";
 65             idx = info.find(key1) + key1.size();
 66             return info.substr(idx, info.find_first_of(key2, idx) - idx);
 67         };
 68 
 69         m_ip = get_val("IP");
 70         m_port = get_val("PORT");
 71         m_zk_path = get_val("ZK_PATH");
 72         m_module_name = get_val("MODULE_NAME");
 73         m_module_id = get_val("MODULE_ID");
 74         m_module_idx = get_val("MODULE_IDX");
 75     }
 76 
 77     void FromJson(const Json::Value& info)
 78     {
 79         m_ip = info["ip"].asString();
 80         m_port = info["port"].asString();
 81         m_zk_path = info["zk_path"].asString();
 82         m_module_name = info["module_name"].asString();
 83         m_module_id = info["module_id"].asString();
 84         m_module_idx = info["module_idx"].asString();
 85         m_reg_type = info["reg_type"].asInt();
 86     }
 87 
 88 public:
 89     string m_ip;
 90     string m_port;
 91     string m_zk_path;
 92     string m_module_name;
 93     string m_module_id;
 94     string m_module_idx;
 95 
 96 public:
 97     int m_reg_type;
 98 };
 99 
100 #endif

 

time_utils.h

 1 #ifndef _TIME_UTILS_H_
 2 #define _TIME_UTILS_H_
 3 
 4 class CTimeUtils
 5 {
 6 public:
 7     static long GetCurTimeS();
 8     static long GetCurTimeMs();
 9     static long GetCurTimeUs();
10 
11 
12 };
13 
14 #endif

 

time_utils.cpp

 1 #include "time_utils.h"
 2 
 3 #include  4 
 5 long CTimeUtils::GetCurTimeS()
 6 {
 7     struct timeval  tv;
 8     struct timezone tz;
 9 
10     tz.tz_minuteswest = 0;
11     tz.tz_dsttime = 0;
12     gettimeofday(&tv, &tz);
13     return  tv.tv_sec;
14 }
15 
16 long CTimeUtils::GetCurTimeMs()
17 {
18     return GetCurTimeUs() / 1000;
19 }
20 
21 long CTimeUtils::GetCurTimeUs()
22 {
23     struct timeval  tv;
24     struct timezone tz;
25     long cur_time_us = 0;
26 
27     tz.tz_minuteswest = 0;
28     tz.tz_dsttime = 0;
29     gettimeofday(&tv, &tz);
30     cur_time_us = tv.tv_sec * 1000000 + tv.tv_usec;
31     return cur_time_us;
32 }

 

zk_define.h

 1 #ifndef _ZK_DEFINE_H_ 
 2 #define _ZK_DEFINE_H_
 3 
 4 const int kMaxBufferLen = 4096;
 5 const int kZkHandleIntervalTime = 1000000;
 6 const int kZkRegisterIntervalTime = 1000000;
 7 const int kZkDiscoveryIntervalTime = 1000000;
 8 
 9 enum EZkRegisterStatus
10 {
11     EN_ZK_REGISTER_STATUS_UNREGISTER = 0,
12     EN_ZK_REGISTER_STATUS_REGISTER,
13     EN_ZK_REGISTER_STATUS_TIMEOUT,
14     EN_ZK_REGISTER_STATUS_UNKNOWN,
15 };
16 
17 enum EZkRegisterType
18 {
19     EN_ZK_REGISTER_TYPE_NORMAL,
20     EN_ZK_REGISTER_TYPE_LOCK,
21 };
22 
23 #endif

 

register.h

 1 #ifndef _REGISTER_H_ 
 2 #define _REGISTER_H_
 3 
 4 #include "base_class.h"
 5 
 6 #include  7 
 8 class CRegister : public CUnCopyable
 9 {
10 private:
11     static pthread_mutex_t m_mutex;
12     static CRegister* m_pins;
13     CRegister();
14 public:
15     static CRegister* GetInstance();
16     int Init(const CNodeInfo & node_info);
17     
18 public:
19     int Register();
20     int UnRegister();
21 
22 private:
23     static void* RegisterCheckThread(void * param);
24     int RegisterCheck();
25     bool IsRunning();
26 
27 private:
28     int TryCheckNode();
29     int TryRegisterNode();
30     int TryUnregisterNode();
31 
32 private:
33     pthread_t m_reg_check_thread_id;
34     bool m_is_running;
35     CNodeInfo m_self_info;
36     struct Stat m_self_stat;
37     EZkRegisterStatus m_status;
38     long m_last_check_time;
39 
40 private:
41     string m_raw_zk_path;
42 };
43 
44 #endif

 

register.cpp

技术图片技术图片
  1 #include "register.h"
  2 #include "auto_lock.h"
  3 #include "zk_handle.h"
  4 #include "time_utils.h"
  5 
  6 #include   7 
  8 #include   9 #include  10 #include  11 
 12 CRegister* CRegister::m_pins = nullptr;
 13 pthread_mutex_t CRegister::m_mutex;
 14 
 15 CRegister::CRegister() 
 16     : m_is_running(false)
 17     , m_reg_check_thread_id(0)
 18     , m_status(EN_ZK_REGISTER_STATUS_UNREGISTER)
 19     , m_last_check_time(0)
 20 {
 21 
 22 }
 23 
 24 CRegister* CRegister::GetInstance()
 25 {
 26     if (m_pins == nullptr)
 27     {
 28         CAutoMutexLock auto_lock(m_mutex);
 29         if (m_pins == nullptr)
 30         {
 31             m_pins = new CRegister;
 32         }
 33     }
 34     return m_pins;
 35 }
 36 
 37 int CRegister::Init(const CNodeInfo& node_info)
 38 {
 39     m_self_info = node_info;
 40     return 0;
 41 }
 42 
 43 int CRegister::Register()
 44 {
 45     if (0 == m_reg_check_thread_id)
 46     {
 47         m_is_running = true;
 48         if (0 != pthread_create(&m_reg_check_thread_id, nullptr, CRegister::RegisterCheckThread, nullptr))
 49         {
 50             printf("CRegister::Register create register check thread fail.\n");
 51             return -1;
 52         }
 53         printf("CRegister::Register create register check thread succ.\n");
 54     }
 55     return 0;
 56 }
 57 
 58 int CRegister::UnRegister()
 59 {
 60     m_is_running = false;
 61     CAutoMutexLock auto_lock(m_mutex);
 62     TryUnregisterNode();
 63 }
 64 
 65 void* CRegister::RegisterCheckThread(void* param)
 66 {
 67     prctl(PR_SET_NAME, "zk_register_check");
 68     while (true == CRegister::GetInstance()->IsRunning())
 69     {
 70         CRegister::GetInstance()->RegisterCheck();
 71         usleep(kZkRegisterIntervalTime);
 72     }
 73     return nullptr;
 74 }
 75 
 76 int CRegister::RegisterCheck()
 77 {
 78     CAutoMutexLock auto_lock(m_mutex);
 79 
 80     //未注册,尝试注册
 81     if (EN_ZK_REGISTER_STATUS_UNREGISTER == m_status)
 82     {
 83         TryRegisterNode();
 84     }
 85 
 86     //已注册,check连接
 87     else if (EN_ZK_REGISTER_STATUS_REGISTER == m_status)
 88     {
 89         TryCheckNode();
 90     }
 91 
 92     //状态未知,check连接
 93     else if (EN_ZK_REGISTER_STATUS_UNKNOWN == m_status)
 94     {
 95         TryCheckNode();
 96     }
 97     return 0;
 98 }
 99 
100 bool CRegister::IsRunning()
101 {
102     return m_is_running;
103 }
104 
105 int CRegister::TryCheckNode()
106 {
107     printf("%s =======================================================\n", __func__);
108     if (EN_ZK_REGISTER_STATUS_UNREGISTER == m_status)
109     {
110         printf("CRegister::TryCheckNode status is un register. don‘t need check\n");
111         return 0;
112     }
113 
114     struct Stat stat;
115     string info;
116     int ret_code = CZkHandle::GetInstance()->ZkGetNodeInfo(m_raw_zk_path, info, stat);
117     if (ZNONODE == ret_code)
118     {
119         printf("CRegister::TryCheckNode node don‘t exists. raw_path=%s\n.", m_raw_zk_path.c_str());
120         m_status = EN_ZK_REGISTER_STATUS_UNREGISTER;
121     }
122     else if (ZOK != ret_code)
123     {
124         printf("CRegister::TryCheckNode something wrong. raw_path=%s ret_code=%d\n.", m_raw_zk_path.c_str(), ret_code);
125         m_status = EN_ZK_REGISTER_STATUS_UNKNOWN;
126     }
127     else if (m_self_info.ToString() != info)
128     {
129         m_status = EN_ZK_REGISTER_STATUS_UNREGISTER;
130         printf("CRegister::TryCheckNode get node succ.but belong to others!\n.");
131     }
132     else
133     {
134         printf("CRegister::TryCheckNode get node succ and check succ!\n.");
135     }
136 }
137 
138 int CRegister::TryRegisterNode()
139 {
140     printf("%s =======================================================\n", __func__);
141     if (EN_ZK_REGISTER_STATUS_UNREGISTER != m_status)
142     {
143         printf("CRegister::TryCheckNode status is not unregister.\n");
144         return 0;
145     }
146 
147     string reg_zk_path = m_self_info.m_zk_path + "/" + m_self_info.m_module_name + "_" + m_self_info.m_module_idx;
148     string raw_node_name;
149     bool is_sequential = m_self_info.m_reg_type == EN_ZK_REGISTER_TYPE_NORMAL;
150     int ret_code = CZkHandle::GetInstance()->ZkCreateNode(reg_zk_path, m_self_info.ToString(), is_sequential, raw_node_name);
151     if (ZNODEEXISTS == ret_code)
152     {
153         printf("CRegister::TryRegisterNode register fail. someone has already register\n");
154         return ret_code;
155     }
156     else if(ZOK != ret_code)
157     {
158         printf("CRegister::TryRegisterNode register fail. ret=%d\n", ret_code);
159         return ret_code;
160     }
161 
162     m_raw_zk_path = raw_node_name;
163 
164     struct Stat stat;
165     string info;
166     ret_code = CZkHandle::GetInstance()->ZkGetNodeInfo(m_raw_zk_path, info, stat);
167     if (ZNONODE == ret_code)
168     {
169         printf("CRegister::TryRegisterNode node don‘t exists. raw_path=%s\n.", m_raw_zk_path.c_str());
170         return ret_code;
171     }
172     else if (ZOK != ret_code)
173     {
174         printf("CRegister::TryRegisterNode something wrong. raw_path=%s ret_code=%d\n.", m_raw_zk_path.c_str(), ret_code);
175         return ret_code;
176     }
177 
178     if (m_self_info.ToString() == info)
179     {
180         m_self_stat = stat;
181         m_status = EN_ZK_REGISTER_STATUS_REGISTER;
182         m_last_check_time = CTimeUtils::GetCurTimeUs();
183         printf("CRegister::TryRegisterNode register succ!\n.");
184     }
185     else
186     {
187         printf("CRegister::TryRegisterNode register fail!\n.");
188     }
189 
190     return ret_code;
191 }
192 
193 int CRegister::TryUnregisterNode()
194 {
195     printf("%s =======================================================\n", __func__);
196     if (EN_ZK_REGISTER_STATUS_UNREGISTER == m_status)
197     {
198         printf("CRegister::TryUnregisterNode status is un register. don‘t need unregister\n");
199         return 0;
200     }
201 
202     struct Stat stat;
203     string info;
204     int ret_code = CZkHandle::GetInstance()->ZkGetNodeInfo(m_raw_zk_path, info, stat);
205     if (ZNONODE == ret_code)
206     {
207         printf("CRegister::TryUnregisterNode node don‘t exists. raw_path=%s\n.", m_raw_zk_path.c_str());
208         m_status = EN_ZK_REGISTER_STATUS_UNREGISTER;
209         return 0;
210     }
211     else if (ZOK != ret_code)
212     {
213         printf("CRegister::TryUnregisterNode something wrong. raw_path=%s ret_code=%d\n.", m_raw_zk_path.c_str(), ret_code);
214         m_status = EN_ZK_REGISTER_STATUS_UNKNOWN;
215         return 0;
216     }
217     else if (m_self_info.ToString() != info)
218     {
219         m_status = EN_ZK_REGISTER_STATUS_UNREGISTER;
220         printf("CRegister::TryUnregisterNode get node succ.but belong to others!\n.");
221         return 0;
222     }
223 
224     ret_code = CZkHandle::GetInstance()->ZkDeleteNode(m_raw_zk_path);
225 
226     if (ZOK != ret_code && ZNONODE != ret_code)
227     {
228         printf("CRegister::TryUnregisterNode unregister fail");
229     }
230     else
231     {
232         printf("CRegister::TryUnregisterNode unregister succ");
233         m_status = EN_ZK_REGISTER_STATUS_UNREGISTER;
234     }
235 
236     return ret_code;
237 }
View Code

 

register_test main.cpp

 1 #include "../zk_util/zk_handle.h"
 2 #include "../zk_util/register.h"
 3 
 4 #include  5 #include  6 
 7 #include  8 #include  9 
10 //伪分布式部署 host list最好以配置文件形式,此处为测试程序,暂时写死
11 const char* host_list = "xx.xx.xx.xx:port,xx.xx.xx.xx:port,xx.xx.xx.xx:port";
12 const int time_out = 3000;
13 int main(int argc, char* argv[])
14 {
15     if (argc != 2)
16     {
17         std::cout "./" 0] " "  std::endl;
18         return -1;
19     }
20 
21     CZkHandle::GetInstance()->ZkInit(host_list, time_out);
22     CNodeInfo node_info;
23 
24     std::ifstream ifs; 
25     ifs.open(argv[1]);
26     if (!ifs.good())
27     {
28         return -1;
29     }
30 
31     Json::Value jsn_conf;
32     Json::Reader jsn_reader;
33     if (jsn_reader.parse(ifs, jsn_conf) == false)
34     {
35         return -2;
36     }
37 
38     node_info.FromJson(jsn_conf);
39 
40     CRegister::GetInstance()->Init(node_info);
41     CRegister::GetInstance()->Register();
42 
43     sleep(60);
44 
45     return 0;
46 }

 

Makefile

 1 INC_DIR:= ./ ../zk_util/ /usr/local/include/zookeeper/ /usr/local/include/json/
 2 SRCS:= $(wildcard ./*cpp ../zk_util/*cpp)
 3 OBJS:= $(patsubst %.cpp, %.o, $(SRCS))
 4 LIBS:= -lpthread -lzookeeper_mt -ljsoncpp
 5 
 6 CXX:= g++
 7 
 8 CXXFLAGS:= -w -g -std=c++11 $(addprefix -I, $(INC_DIR)) $(LIBS) -Wl,-rpath="/usr/local/lib"
 9 
10 EXE:= ../../bin/register_test
11 
12 $(EXE):$(OBJS)
13     $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS)
14 
15 clean:
16     rm -rf $(EXE)
17     rm -rf $(OBJS)

 

register_test_1.conf 

1 {
2         "ip":"127.0.0.1",
3         "port":"12345",
4         "zk_path":"/zk_test1",
5         "module_name":"register_test",
6         "module_id":"1",
7         "module_idx":"1",
8         "reg_type":1
9 }

 

register_test_2.conf

1 {
2         "ip":"127.0.0.1",
3         "port":"12345",
4         "zk_path":"/zk_test2",
5         "module_name":"register_test",
6         "module_id":"2",
7         "module_idx":"2",
8         "reg_type":0
9 }

 

加锁注册测试:使用register_test_1.conf 启动多个测试程序

第一个:

ccx@ccx:~/self_test/zookeeper/services_register_and_discovery/bin$ ll
total 2228
drwxrwxrwx 1 ccx ccx     512 May 30 18:35 ./
drwxrwxrwx 1 ccx ccx     512 May 30 18:20 ../
-rwxrwxrwx 1 ccx ccx 1187296 May 30 18:35 register_test*
-rwxrwxrwx 1 ccx ccx 1092352 May 30 18:24 zk_handle_test*
ccx@ccx:~/self_test/zookeeper/services_register_and_discovery/bin$ ./register_test ../conf/register_test_1.conf 
CZkHandle::ZkInit create register check thread succ.
CRegister::Register create register check thread succ.
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkCreateNode create node fail. ret=-8
CRegister::TryRegisterNode register fail. ret=-8
CZkHandle::ResetZkHandle: connect to zk succ.
CZkHandle::ZkInitWatchar: [type=-1] [state=3] [path=] [watcher_ctx=(nil)]
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkCreateNode create node succ! path=/zk_test1/register_test_1
CZkHandle::ZkGetNodeInfo get node info for path=/zk_test1/register_test_1
CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
CZkHandle::ZkGetNodeInfo get node info for path=/zk_test1/register_test_1 succ. buffer=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] 
CZkHandle::ZkGetNodeInfo: [path=/zk_test1/register_test_1] [czxid=17179873759] [mzxid=17179873759] [version=0] [cversion=0] [child_num=0]
CRegister::TryRegisterNode register succ!
.CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
TryCheckNode =======================================================
CZkHandle::ZkGetNodeInfo get node info for path=/zk_test1/register_test_1
CZkHandle::ZkGetNodeInfo get node info for path=/zk_test1/register_test_1 succ. buffer=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] 
CZkHandle::ZkGetNodeInfo: [path=/zk_test1/register_test_1] [czxid=17179873759] [mzxid=17179873759] [version=0] [cversion=0] [child_num=0]
CRegister::TryCheckNode get node succ and check succ!
.TryCheckNode =======================================================
CZkHandle::ZkGetNodeInfo get node info for path=/zk_test1/register_test_1
CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
CZkHandle::ZkGetNodeInfo get node info for path=/zk_test1/register_test_1 succ. buffer=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] 
CZkHandle::ZkGetNodeInfo: [path=/zk_test1/register_test_1] [czxid=17179873759] [mzxid=17179873759] [version=0] [cversion=0] [child_num=0]
CRegister::TryCheckNode get node succ and check succ!

第二个:

ccx@ccx:~/self_test/zookeeper/services_register_and_discovery/bin$ ./register_test ../conf/register_test_1.conf 
CZkHandle::ZkInit create register check thread succ.
CRegister::Register create register check thread succ.
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkCreateNode create node fail. ret=-8
CRegister::TryRegisterNode register fail. ret=-8
CZkHandle::ResetZkHandle: connect to zk succ.
CZkHandle::ZkInitWatchar: [type=-1] [state=3] [path=] [watcher_ctx=(nil)]
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkCreateNode create node fail. ret=-110
CRegister::TryRegisterNode register fail. someone has already register
CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
CZkHandle::ZkCreateNode create node fail. ret=-110
CRegister::TryRegisterNode register fail. someone has already register
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
CZkHandle::ZkCreateNode create node fail. ret=-110
CRegister::TryRegisterNode register fail. someone has already register

 

第一个stop之后的第二个:

TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] PORT[12345] ZK_PATH[/zk_test1] MODULE_NAME[register_test] MODULE_ID[1] MODULE_IDX[1] ]
CZkHandle::ZkExists: [ret=0]
CZkHandle::ZkExists: [path=/] [czxid=0] [mzxid=0] [version=0] [cversion=291] [child_num=5]
CZkHandle::ZkCreateNode create node fail. ret=-110
CRegister::TryRegisterNode register fail. someone has already register
TryRegisterNode =======================================================
CZkHandle::ZkCreateNode create node [path=/zk_test1/register_test_1] [value=IP[127.0.0.1] P


评论


亲,登录后才可以留言!