46-微服务技术栈(高级):分布式协调服务zookeeper源码篇(Watcher机制-1)

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介:   前面已经分析了Zookeeper持久话相关的类,下面接着分析Zookeeper中的Watcher机制所涉及到的类。

一、前言

  前面已经分析了Zookeeper持久话相关的类,下面接着分析Zookeeper中的Watcher机制所涉及到的类。

二、总体框图

  对于Watcher机制而言,主要涉及的类主要如下。

  

说明:

Watcher

接口类型,其定义了process方法,需子类实现

Event

接口类型,Watcher的内部类,无任何方法

KeeperState

枚举类型,Event的内部类,表示Zookeeper所处的状态

EventType

枚举类型,Event的内部类,表示Zookeeper中发生的事件类型

WatchedEvent

表示对ZooKeeper上发生变化后的反馈,包含了KeeperState和EventType

ClientWatchManager

接口类型,表示客户端的Watcher管理者,其定义了materialized方法,需子类实现

ZKWatchManager

Zookeeper的内部类,继承ClientWatchManager

MyWatcher

ZooKeeperMain的内部类,继承Watcher

ServerCnxn

接口类型,继承Watcher,表示客户端与服务端的一个连接

WatchManager

管理Watcher

三、Watcher源码分析

3.1 内部类

  Event,接口类型,表示事件代表的状态,除去其内部类,其源码结构如下

public interface Watcher {


   public interface Event {

       /**

        * Enumeration of states the ZooKeeper may be at the event

        */

       public enum KeeperState {


           @Deprecated

           Unknown (-1),


           Disconnected (0),


           @Deprecated

           NoSyncConnected (1),


           SyncConnected (3),


           AuthFailed (4),


           ConnectedReadOnly (5),


           SaslAuthenticated(6),


           Expired (-112);


           private final int intValue;    


           KeeperState(int intValue) {

               this.intValue = intValue;

           }


           public int getIntValue() {

               return intValue;

           }


           public static KeeperState fromInt(int intValue) {

               switch(intValue) {

                   case   -1: return KeeperState.Unknown;

                   case    0: return KeeperState.Disconnected;

                   case    1: return KeeperState.NoSyncConnected;

                   case    3: return KeeperState.SyncConnected;

                   case    4: return KeeperState.AuthFailed;

                   case    5: return KeeperState.ConnectedReadOnly;

                   case    6: return KeeperState.SaslAuthenticated;

                   case -112: return KeeperState.Expired;


                   default:

                       throw new RuntimeException("Invalid integer value for conversion to KeeperState");

               }

           }

       }


       /**

        * Enumeration of types of events that may occur on the ZooKeeper

        */

       public enum EventType {

           None (-1),

           NodeCreated (1),

           NodeDeleted (2),

           NodeDataChanged (3),

           NodeChildrenChanged (4);


           private final int intValue;    


           EventType(int intValue) {

               this.intValue = intValue;

           }


           public int getIntValue() {

               return intValue;

           }


           public static EventType fromInt(int intValue) {

               switch(intValue) {

                   case -1: return EventType.None;

                   case  1: return EventType.NodeCreated;

                   case  2: return EventType.NodeDeleted;

                   case  3: return EventType.NodeDataChanged;

                   case  4: return EventType.NodeChildrenChanged;


                   default:

                       throw new RuntimeException("Invalid integer value for conversion to EventType");

               }

           }          

       }

   }

}

说明:可以看到,Event接口并没有定义任何属性和方法,但其包含了KeeperState和EventType两个内部枚举类。

可以简化成:

public interface Event {}

3.2 接口方法  

abstract public void process(WatchedEvent event);

说明:其代表了实现Watcher接口时必须实现的的方法,即定义进行处理,WatchedEvent表示观察的事件。

四、Event源码分析(即3.1内部类)

4.1 内部类

1. KeeperState 

public enum KeeperState { // 事件发生时Zookeeper的状态

   /** Unused, this state is never generated by the server */

   @Deprecated

   // 未知状态,不再使用,服务器不会产生此状态

   Unknown (-1),


   /** The client is in the disconnected state - it is not connected

   * to any server in the ensemble. */

   // 断开

   Disconnected (0),


   /** Unused, this state is never generated by the server */

   @Deprecated

   // 未同步连接,不再使用,服务器不会产生此状态

   NoSyncConnected (1),


   /** The client is in the connected state - it is connected

   * to a server in the ensemble (one of the servers specified

   * in the host connection parameter during ZooKeeper client

   * creation). */

   // 同步连接状态

   SyncConnected (3),


   /**

   * Auth failed state

   */

   // 认证失败状态

   AuthFailed (4),


   /**

   * The client is connected to a read-only server, that is the

   * server which is not currently connected to the majority.

   * The only operations allowed after receiving this state is

   * read operations.

   * This state is generated for read-only clients only since

   * read/write clients aren't allowed to connect to r/o servers.

   */

   // 只读连接状态

   ConnectedReadOnly (5),


   /**

   * SaslAuthenticated: used to notify clients that they are SASL-authenticated,

   * so that they can perform Zookeeper actions with their SASL-authorized permissions.

   */

   // SASL认证通过状态

   SaslAuthenticated(6),


   /** The serving cluster has expired this session. The ZooKeeper

   * client connection (the session) is no longer valid. You must

   * create a new client connection (instantiate a new ZooKeeper

   * instance) if you with to access the ensemble. */

   // 过期状态

   Expired (-112);


   // 代表状态的整形值

   private final int intValue;     // Integer representation of value

   // for sending over wire



   // 构造函数

   KeeperState(int intValue) {

       this.intValue = intValue;

   }


   // 返回整形值

   public int getIntValue() {

       return intValue;

   }


   // 从整形值构造相应的状态

   public static KeeperState fromInt(int intValue) {

       switch(intValue) {

           case   -1: return KeeperState.Unknown;

           case    0: return KeeperState.Disconnected;

           case    1: return KeeperState.NoSyncConnected;

           case    3: return KeeperState.SyncConnected;

           case    4: return KeeperState.AuthFailed;

           case    5: return KeeperState.ConnectedReadOnly;

           case    6: return KeeperState.SaslAuthenticated;

           case -112: return KeeperState.Expired;


           default:

               throw new RuntimeException("Invalid integer value for conversion to KeeperState");

       }

   }

}

说明:KeeperState是一个枚举类,其定义了在事件发生时Zookeeper所处的各种状态,其还定义了一个从整形值返回对应状态的方法fromInt。

2. EventType 

public enum EventType { // 事件类型

   // 无

   None (-1),

   // 结点创建

   NodeCreated (1),

   // 结点删除

   NodeDeleted (2),

   // 结点数据变化

   NodeDataChanged (3),

   // 结点子节点变化

   NodeChildrenChanged (4);


   // 代表事件类型的整形

   private final int intValue;     // Integer representation of value

   // for sending over wire


   // 构造函数

   EventType(int intValue) {

       this.intValue = intValue;

   }


   // 返回整形

   public int getIntValue() {

       return intValue;

   }


   // 从整形构造相应的事件

   public static EventType fromInt(int intValue) {

       switch(intValue) {

           case -1: return EventType.None;

           case  1: return EventType.NodeCreated;

           case  2: return EventType.NodeDeleted;

           case  3: return EventType.NodeDataChanged;

           case  4: return EventType.NodeChildrenChanged;


           default:

               throw new RuntimeException("Invalid integer value for conversion to EventType");

       }

   }          

}

说明:EventType是一个枚举类,其定义了事件的类型(如创建节点、删除节点等事件),同时,其还定义了一个从整形值返回对应事件类型的方法fromInt。

五、WatchedEvent

5.1 类的属性 

public class WatchedEvent {

   // Zookeeper的状态

   final private KeeperState keeperState;

   // 事件类型

   final private EventType eventType;

   // 事件所涉及节点的路径

   private String path;

}

说明:WatchedEvent类包含了三个属性,分别代表事件发生时Zookeeper的状态、事件类型和发生事件所涉及的节点路径。

5.2 构造函数

  1. public WatchedEvent(EventType eventType, KeeperState keeperState, String path)型构造函数 

public WatchedEvent(EventType eventType, KeeperState keeperState, String path) {

   // 初始化属性

   this.keeperState = keeperState;

   this.eventType = eventType;

   this.path = path;

}

  说明:构造函数传入了三个参数,然后分别对属性进行赋值操作。

  2. public WatchedEvent(WatcherEvent eventMessage)型构造函数  

public WatchedEvent(WatcherEvent eventMessage) {

   // 从eventMessage中取出相应属性进行赋值

   keeperState = KeeperState.fromInt(eventMessage.getState());

   eventType = EventType.fromInt(eventMessage.getType());

   path = eventMessage.getPath();

}

  说明:构造函数传入了WatcherEvent参数,之后直接从该参数中取出相应属性进行赋值操作。

五总结:对于WatchedEvent类的方法而言,相对简单,包含了几个getXXX方法,用于获取相应的属性值。

六、ClientWatchManager

public Set<Watcher> materialize(Watcher.Event.KeeperState state,

                               Watcher.Event.EventType type, String path);

  说明:该方法表示事件发生时,返回需要被通知的Watcher集合,可能为空集合。

七、ZKWatchManager(zookeeper内)

7.1 类的属性

private static class ZKWatchManager implements ClientWatchManager {

   

   // 数据变化的Watchers

   private final Map<String, Set<Watcher>> dataWatches = new HashMap<String, Set<Watcher>>();

   

   // 节点存在与否的Watchers

   private final Map<String, Set<Watcher>> existWatches = new HashMap<String, Set<Watcher>>();

   

   // 子节点变化的Watchers

   private final Map<String, Set<Watcher>> childWatches = new HashMap<String, Set<Watcher>>();

}

 说明:ZKWatchManager实现了ClientWatchManager,并定义了三个Map键值对,键为节点路径,值为Watcher。分别对应数据变化的Watcher、节点是否存在的Watcher、子节点变化的Watcher。

7.2 核心方法分析

1. materialize方法

public Set<Watcher> materialize(Watcher.Event.KeeperState state,

                               Watcher.Event.EventType type,

                               String clientPath)

{

   // 新生成结果Watcher集合

   Set<Watcher> result = new HashSet<Watcher>();


   switch (type) { // 确定事件类型

       case None: // 无类型

           // 添加默认Watcher

           result.add(defaultWatcher);

           // 是否需要清空(提取对zookeeper.disableAutoWatchReset字段进行配置的值、

           // Zookeeper的状态是否为同步连接)

           boolean clear = ClientCnxn.getDisableAutoResetWatch() &&

               state != Watcher.Event.KeeperState.SyncConnected;

  // 同步块

           synchronized(dataWatches) {

               for(Set<Watcher> ws: dataWatches.values()) {

                   // 添加至结果集合

                   result.addAll(ws);

               }

               if (clear) { // 是否需要清空

                   dataWatches.clear();

               }

           }

           // 同步块

           synchronized(existWatches) {  

               for(Set<Watcher> ws: existWatches.values()) {

                   // 添加至结果集合

                   result.addAll(ws);

               }

               if (clear) { // 是否需要清空

                   existWatches.clear();

               }

           }

           

  // 同步块

           synchronized(childWatches) {

               for(Set<Watcher> ws: childWatches.values()) {

                   // 添加至结果集合

                   result.addAll(ws);

               }

               if (clear) { // 是否需要清空

                   childWatches.clear();

               }

           }

           // 返回结果

           return result;

       case NodeDataChanged: // 节点数据变化

       case NodeCreated: // 创建节点

           synchronized (dataWatches) { // 同步块

               // 移除clientPath对应的Watcher后全部添加至结果集合

               addTo(dataWatches.remove(clientPath), result);

           }

           synchronized (existWatches) {

               // 移除clientPath对应的Watcher后全部添加至结果集合

               addTo(existWatches.remove(clientPath), result);

           }

           break;

       case NodeChildrenChanged: // 节点子节点变化

           synchronized (childWatches) {

               // 移除clientPath对应的Watcher后全部添加至结果集合

               addTo(childWatches.remove(clientPath), result);

           }

           break;

       case NodeDeleted: // 删除节点

           synchronized (dataWatches) {

               // 移除clientPath对应的Watcher后全部添加至结果集合

               addTo(dataWatches.remove(clientPath), result);

           }

           // XXX This shouldn't be needed, but just in case

           synchronized (existWatches) {

               // 移除clientPath对应的Watcher

               Set<Watcher> list = existWatches.remove(clientPath);

               if (list != null) {

                   // 移除clientPath对应的Watcher后全部添加至结果集合

                   addTo(existWatches.remove(clientPath), result);

                   LOG.warn("We are triggering an exists watch for delete! Shouldn't happen!");

               }

           }

           synchronized (childWatches) {

               // 移除clientPath对应的Watcher后全部添加至结果集合

               addTo(childWatches.remove(clientPath), result);

           }

           break;

       default: // 缺省处理

           String msg = "Unhandled watch event type " + type

               + " with state " + state + " on path " + clientPath;

           LOG.error(msg);

           throw new RuntimeException(msg);

   }


   // 返回结果集合

   return result;

}

说明:该方法在事件发生后,返回需要被通知的Watcher集合。在该方法中,首先会根据EventType类型确定相应的事件类型,然后根据事件类型的不同做出相应的操作:

如针对None类型,即无任何事件,则首先会从三个键值对中删除clientPath对应的Watcher,然后将剩余的Watcher集合添加至结果集合;

针对NodeDataChanged和NodeCreated事件而言,其会从dataWatches和existWatches中删除clientPath对应的Watcher,然后将剩余的Watcher集合添加至结果集合。

八、总结

  针对Watcher机制的第一部分的源码分析就已经完成,本章节需重点关注:

  • 事件的变化,状态的定义依赖于Event内部类的两组枚举值
  • 上下游调用关系图需记忆一下,为加强记忆,再最后再贴一下

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
24天前
|
Kubernetes 负载均衡 Docker
构建高效后端服务:微服务架构的探索与实践
【10月更文挑战第20天】 在数字化时代,后端服务的构建对于任何在线业务的成功至关重要。本文将深入探讨微服务架构的概念、优势以及如何在实际项目中有效实施。我们将从微服务的基本理念出发,逐步解析其在提高系统可维护性、扩展性和敏捷性方面的作用。通过实际案例分析,揭示微服务架构在不同场景下的应用策略和最佳实践。无论你是后端开发新手还是经验丰富的工程师,本文都将为你提供宝贵的见解和实用的指导。
|
23天前
|
监控 API 持续交付
构建高效后端服务:微服务架构的深度探索
【10月更文挑战第20天】 在数字化时代,后端服务的构建对于支撑复杂的业务逻辑和海量数据处理至关重要。本文深入探讨了微服务架构的核心理念、实施策略以及面临的挑战,旨在为开发者提供一套构建高效、可扩展后端服务的方法论。通过案例分析,揭示微服务如何帮助企业应对快速变化的业务需求,同时保持系统的稳定性和灵活性。
46 9
|
25天前
|
监控 安全 Java
构建高效后端服务:微服务架构深度解析与最佳实践###
【10月更文挑战第19天】 在数字化转型加速的今天,企业对后端服务的响应速度、可扩展性和灵活性提出了更高要求。本文探讨了微服务架构作为解决方案,通过分析传统单体架构面临的挑战,深入剖析微服务的核心优势、关键组件及设计原则。我们将从实际案例入手,揭示成功实施微服务的策略与常见陷阱,为开发者和企业提供可操作的指导建议。本文目的是帮助读者理解如何利用微服务架构提升后端服务的整体效能,实现业务快速迭代与创新。 ###
60 2
|
30天前
|
消息中间件 Kafka 数据库
微服务架构中,如何确保服务之间的数据一致性?
微服务架构中,如何确保服务之间的数据一致性?
|
27天前
|
运维 Kubernetes 开发者
构建高效后端服务:微服务架构与容器化技术的结合
【10月更文挑战第18天】 在数字化转型的浪潮中,企业对后端服务的要求日益提高,追求更高的效率、更强的可伸缩性和更易于维护的系统。本文将探讨微服务架构与容器化技术如何结合,以构建一个既灵活又高效的后端服务体系。通过分析当前后端服务面临的挑战,介绍微服务和容器化的基本概念,以及它们如何相互配合来优化后端服务的性能和管理。本文旨在为开发者提供一种实现后端服务现代化的方法,从而帮助企业在竞争激烈的市场中脱颖而出。
25 0
|
10天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
51 6
|
10天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
27 1
|
2月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
2月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
3月前
|
Kubernetes Cloud Native Docker
云原生之旅:从容器到微服务的架构演变
【8月更文挑战第29天】在数字化时代的浪潮下,云原生技术以其灵活性、可扩展性和弹性管理成为企业数字化转型的关键。本文将通过浅显易懂的语言和生动的比喻,带领读者了解云原生的基本概念,探索容器化技术的奥秘,并深入微服务架构的世界。我们将一起见证代码如何转化为现实中的服务,实现快速迭代和高效部署。无论你是初学者还是有经验的开发者,这篇文章都会为你打开一扇通往云原生世界的大门。

相关产品

  • 微服务引擎