Working with scenes
The entire system is divided into master and server two roles, and each master and server needs to know the list of servers currently available within the cluster.
The original processing mode: Master is responsible for the collection and distribution of cluster server information. Server startup and master establish long connections and heartbeat detection, master collects new and disconnect servers, and distributes the collected information to all servers.
Original problem: Master and server are heavily coupled; Master is harder to extend. How to use Overview
Each server corresponds to a child node of a zookeeper, all master and push obtains the server list by fetching all child nodes, and when the server disconnect zookeeper notifies all machines to retrieve the server list again. detailed
root Node Road strength:/service/serverlist
1. Initialize the Zookeeper connection
publicstatic void Initzk () {
try{
#初始化, if there is currently a alive ZK connection, the if is not initialized
(ZK = null| |!zk.getstate (). IsAlive ( ) {
synchronized (obj) {
if (ZK = null| |!zk.getstate (). IsAlive ()) {
# # #把之前的close掉
Closezk ();
PropertyReader p = newpropertyreader (zk_properties_file);
String zkserverstr = p.getvalueasstring ("Zookeeper.server", Zk_server_str_default);
Intsessiontimeout = P.getvalueasint ("Zookeeper.sessiontimeout", zk_session_timeout);
# # #重新建立连接
ZK = Newzookeeper (Zkserverstr, Sessiontimeout,newdefaultwatcher ());}}}
catch (Exception e) {
thrownew runtimeexception ("Zookeeper Init error!", e);
}
2.server adds a temporary node representing itself and watch its parent node at startup
### #如果之前myNodeName已经存在, delete
zkutils.deletenode (mynodename);
### #先看看父节点有没有, not on the creation of the next, the parent node is a persistent
zkutils.createnode (rootnode,createmode.persistent);
### #添加对父节点child变动的watcher
Zkutils.addchildwatch (Rootnode,serverlistwatcher.getinstance ());
# # #创建自己的节点mynode
Zkutils.createnode (mynodename,createmode.ephemeral);
3.master Watch parent node at startup
### #先看看父节点有没有, not on the creation of the next, the parent node is a persistent
zkutils.createnode (rootnode,createmode.persistent);
### #添加对父节点child变动的watcher
Zkutils.addchildwatch (Rootnode,serverlistwatcher.getinstance ());
4. Monitor the child changes of the parent node and process
Publicvoid process (Watchedevent event) {try{# # #如果是expired, you need to reinitialize the IF (Event.getstate ()
= = keeperstate.expired) {while (true) {try{//reinitialization of ZK connections
Zkutils.initzk ();
Reinitialize related ZK node pushzkutils.initpushzknodes ();
Obtain NodeList getandsavenodelist ();
If successful, then break;
Break }catch (RuntimeException e) {asynclogger.getinstance (). info (Logmanager.service_log, "SERVERLISTWATC
Her:init error! ");
5s after Thread.Sleep (5* 1000); # # # # #如果是断开重连, need to retrieve the next list to avoid losing events if (event.getstate () = Keeperstate .
syncconnected) {getandsavenodelist (); }
###如果是child变化, and the Pushserver list is changed, get the list, save the Local if (event.gettype () = = eventtype.nodechildrenchanged) {
Asynclogger.getinstance (). info (logmanager.service_log, "Serverlistwatcher:node child Changed Event Received");
Save to local, wait for sync thread to check getandsavenodelist (); }}catch (Exception e) {}}
Attention Matters the use of watcher
1.watcher Classification
Watcher mainly has the following add way, different add the way monitor different action. (when setting watcher, if the corresponding server already does not exist Node,watcher is not left on the service side)
# # #获取节点数据, in the first method, Watch=true represents the default watcher that was passed in when zookeeper was created, monitoring actions sets data on the node, or deletes the node.
Publicbyte[] GetData (String path, Booleanwatch, Stat Stat)
publicbyte[] GetData (finalstring path, Watcher Watcher, Stat Stat)
# # #判断节点是否存在, the first method watch=true represents the default watcher that is passed in when the zookeeper is created, and monitoring actions creates/delete the node or sets the Data on the node.
Publicstat exists (finalstring path, Watcher Watcher)
Publicstat exists (String path, booleanwatch)
### Gets the node child, in the first method, Watch=true represents the default watcher that was passed in when the zookeeper was created, monitoring actions deletes the node of the given path or creates/delete a child u NDEr the node
publiclist<string> getchildren (finalstring path, Watcher watcher)
publiclist<string > GetChildren (String path, Booleanwatch)
the use of 2.watcher attention
The following points need to be paid more attention to when using the watcher is one-time, after each processing event need to be added again. The event changes between the processing and the added interval are not known.
# # #获取的时候把watcher重新加一次
Events that occur while the client is disconnect with zookeeper may be lost.
# # #如果是断开重连, you need to retrieve the next list to avoid losing the event
if (event.getstate () = = keeperstate.syncconnected) {
getandsavenodelist ();
}
If the session expires, all watcher will be wood.
if (event.getstate () = = keeperstate.expired) {while
(true) {
try{
//Reinitialize ZK connection
Zkutils.initzk ();
Reinitialize related ZK node
pushzkutils.initpushzknodes ();
Obtain NodeList
getandsavenodelist ();
If successful, then break;
break;
catch (RuntimeException e) {
asynclogger.getinstance (). info (Logmanager.service_log, "Serverlistwatcher:init Error! ");
5s after
Thread.Sleep (5*1000);
}
Connectionloss and Sessionexpired
Because of the network environment and other reasons, these two anomalies will appear from time to time, need to consider these circumstances.
Connectionloss said that the connection was not available, and ZK's Java client automatically took the current SessionID to the other zkserver to establish a connection.
If the connection succeeds within the sessiontimeout time, everything returns to normal and the temporary node and watcher are not lost.
If the connection is zkserver after sessiontimeout time, then Zkserver returns to session expired, which is not available, the temporary node and the watcher are lost, and the new initialization needs to be manually flushed.
When PS:ZK is instantiated, a sessiontimeout parameter is passed in, and the ZK server configures the Minsessiontimeout (default 2*ticktime) and maxsessiontimeout locally after receiving this parameter (default 20* Ticktime) for comparison and interception.