El mecanismo watcher de Zookeeper se puede dividir en cuatro procesos:
- El cliente registra el watcher.
- El servidor procesa el watcher.
- El servidor activa el evento watcher.
- El cliente realiza la devolución de llamada del watcher.
Entre ellas, el cliente tiene tres formas de registrar watchers. Llamando a la API del cliente se puede implementar mediante getData, exists y getChildren respectivamente. Utilizando el proyecto Maven creado en el capítulo anterior, cree una nueva clase WatcherDemo y tome el método exists como ejemplo para explicar su principio.
Ejemplo
static ZooKeeper zooKeeper;
static {
try {
zooKeeper = new ZooKeeper("192.168.3.39:2181", 4000,new WatcherDemo());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent event) {
System.out.println("eventType:"+event.getType());
if(event.getType()==Event.EventType.NodeDataChanged){
try {
zooKeeper.exists(event.getPath(),true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
String path="/watcher";
if(zooKeeper.exists(path,false)==null) {
zooKeeper.create("/watcher", "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
Thread.sleep(1000);
System.out.println("-----------");
// true indica que se usa el watcher configurado en la instancia de Zookeeper
Stat stat=zooKeeper.exists(path,true);
System.in.read();
}
}
Después de ejecutar el programa, la consola muestra:

En este momento, inicie la terminal de línea de comandos de Zookeeper, consulte y eliminewatcherel nodo:

La consola del IDE muestra que se activó el evento de eliminación del nodo:

El cliente envía solicitudes al servidor a través de una conexión larga TCP para establecer el canal de red. Por defecto, la capa subyacente usa el método NIO de Java, y también se puede configurar el método de implementación con Netty.

Diagrama de flujo del registro del evento de escucha del watcher:

1. El cliente envía una solicitud de notificación de eventos
Cuando la clase Zookeeper llama al método exists, encapsula la creación de la escucha de eventos en el objeto request y establece el atributo watch en true. Cuando el servidor devuelve la respuesta, encapsula el evento de escucha en la clase ZKWatchManager del cliente.

2. El servidor procesa la solicitud del evento watcher
La clase NIOServerCnxn del servidor se utiliza para procesar las solicitudes enviadas por el cliente, y finalmente llama a FinalRequestProcessor. Entre ellas, hay un fragmento de código fuente que agrega el evento watcher enviado por el cliente:

Luego ingresa al método statNode, agrega el evento watcher en el método de la clase DataTree y lo guarda en watchTable y watchTable de WatchManager.


3. Proceso del servidor al activar el evento watcher:
Si un nodo supervisado en el servidor recibe una solicitud de transacción, durante el procesamiento de la solicitud, el servidor llama al método processRequest de la clase FinalRequestProcessor, cuyo código es el siguiente:

La cadena de llamadas de eliminación finalmente llega al fragmento de código de activación de la rama de eliminación de nodos en la clase DataTree:

Ingrese al método triggerWatch de la clase WatchManager:

Continúe rastreando e ingrese a NIOServerCnxn. Se construye un objeto ReplyHeader con xid de -1 y zxid de -1, y luego se llama al método sendResonpe.

4. El cliente gestiona la devolución de llamada del evento watcher
El método readResponse de la clase SendThread del cliente recibe la notificación de eventos activada por el servidor, ingresa al flujo con xid de -1 y procesa el evento Event.


Descargar el código fuente de este capítulo
Download