- 自序
- 概述
- 安装和运行 Zookeeper
- Zookeeper 开发实例
- ZooKeeper 中的组和成员
- 创建组
- 加入组
- 成员列表
- 删除分组
- Zookeeper 服务
- 数据模型 Data Model
- 操作 Operations
- 实现 Implementation
- 数据一致性 Consistency
- 会话 Sessions
- ZooKeeper 应用程序 Building Applications with ZooKeeper
- 配置服务 Configuration Service
- 坚韧的 ZooKeeper 应用 The Resilient ZooKeeper Application
- 一个稳定的配置服务 A reliable configuration service
- 生产环境中的 ZooKeeper ZooKeeper in Production
- 韧性和性能 Resilience and Performance
- 配置
坚韧的 ZooKeeper 应用 The Resilient ZooKeeper Application
分布式计算设计的第一谬误就是认为“网络是稳定的”。我们所实现的程序目前都是假设网络稳定的情况下实现的,所以当我们在一个真实的网络环境下,会有很多原因可以使程序执行失败。下面我们将阐述一些可能造成失败的场景,并且讲述如何正确的处理这些失败,让我们的程序在面对这些异常时更具韧性。
在 ZooKeeper 的 API 中,每一个 ZooKeeper 的操作都会声明抛出两个异常:InterruptedException 和 KeeperException。
InterrupedException
当一个操作被中断时,会抛出一个 InterruptedException。在 JAVA 中有一个标准的阻塞机制用来取消程序的执行,就是在需要阻塞的的地方调用 interrupt()
。如果取消执行成功,会以抛出一个 InterruptedException 作为结果。ZooKeeper 坚持了这个标准,所以我们可以用这种方式来取消 client 的对 ZooKeeper 的操作。用到 ZooKeeper 的类和库需要向上抛出 InterruptedException,才能使我们的 client 实现取消操作。
InterruptedException 并不意味着程序执行失败,可能是人为设计中断的,所以在上面配置应用的例子中,当向上抛出 InterruptedException 时,会引起应用终止。
KeeperException
当 ZooKeeper 服务器出现错误信号,或者出现了通信方面的问题,就会抛出一个 KeeperException。由于错误的不同原因,所以 KeeperException 有很多子类。例如, KeeperException.NoNodeException
当操作一个 znode 时,而这个 znode 并不存在,就会抛出这个异常。
每一个之类都有一个异常码作为异常的类型。例如, KeeperException.NoNodeException
的异常码就是 KeeperException.Code.NONODE
(一个枚举值)。
有两种方法来处理 KeeperException。一种是直接捕获 KeeperException,然后根据异常码进行不同类型异常处理。另一种是捕获具体的子类,然后根据不同类型的异常进行处理。
KeeperException 包含了 3 大类异常。
状态异常 State Exception
当无法操作 znode 树造成操作失败时,会产生状态异常。通常引起状态异常的原因是有另外的程序在同时改变 znode。例如,一个 setData()
操作时,会抛出 KeeperException.BadVersionException
。因为另外的一个程序已经在 setData()
操作之前修改了 znode,造成 setData()
操作时版本号不匹配了。程序员必须了解,这种情况是很有可能发生的,我们必须靠编写处理这种异常的代码来解决他。
有的一些异常是编写代码时的疏忽造成的,例如 KeeperException.NoChildrenForEphemeralsException
。这个异常是当我们给一个 enphemeral 类型的 znode 添加子节点时抛出的。
重新获取异常 Recoverable Exception
重新获取异常来至于那些能够获得同一个 ZooKeeper session 的应用。伴随的表现是抛出 KeeperException.ConnectionLossException
,表示与 ZooKeeper 的连接丢失。ZooKeeper 将会尝试重新连接,大多数情况下重新连接都会成功并且能够保证 session 的完整性。
然而,ZooKeeper 无法通知客户端操作由于 KeeperException.ConnectionLossException
而失败。这就是一个部分失败的例子。只能依靠程序员编写代码来处理这个不确定性。
在这点上,幂等操作和非幂等操作的差别就会变得非常有用了。一个幂等操作是指无论运行一次还是多次结果都是一样的,例如一个读请求,或者一个不设置任何值得 setData 操作。这些操作可以不断的重试。
一个非幂等操作不能被不分青红皂白的不停尝试执行,就像一些操作执行一次的效率和执行多次的效率是不同。我们将在之后会讨论如何利用非幂等操作来处理 Recovreable Exception。
不能重新获取异常 Unrecoverable exceptions
在一些情况下,ZooKeeper 的 session 可能会变成不可用的——比如 session 过期,或者因为某些原因 session 被 close 掉(都会抛出 KeeperException.SessionExpiredException),或者鉴权失败(KeeperException.AuthFailedException)。无论何种情况,ephemeral 类型的 znode 上关联的 session 都会丢失,所以应用在重新连接到 ZooKeeper 之前都需要重新构建他的状态。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论