Zookeeper 集群管理器

这是一个使用 Zookeeper 实现的 Vert.x 集群管理器。

它完全实现了 vert.x 集群的接口。所以如果你愿意,你可以用它来替代 vertx-hazelcast。此实现已打包在内。

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-zookeeper</artifactId>
  <version>5.0.1</version>
</dependency>

在 Vert.x 中,集群管理器用于多种功能,包括

  • 集群中 Vert.x 节点的发现和组成员管理

  • 维护集群范围的主题订阅者列表(以便我们知道哪些节点对哪些事件总线地址感兴趣)

  • 分布式 Map 支持

  • 分布式锁

  • 分布式计数器

集群管理器**不**处理事件总线节点间传输,这由 Vert.x 通过 TCP 连接直接完成。

工作原理

我们使用 Apache Curator 框架而不是直接使用 zookeeper 客户端,因此我们依赖 Curator 中使用的库,例如 guavaslf4j 当然还有 zookeeper

由于 ZK 使用树形字典存储数据,我们可以将根路径作为命名空间。默认根路径是 io.vertx,它在 default-zookeeper.json 中。还有另外 5 个子路径用于记录 Vert.x 集群管理器中其他功能的信息,所有你可以更改的路径是根路径

您可以在 /io.vertx/cluster/nodes/ 路径中找到所有 Vert.x 节点信息,/io.vertx/asyncMap/$name/ 记录您使用 io.vertx.core.shareddata.AsyncMap 接口创建的所有 AsyncMap/io.vertx/asyncMultiMap/$name/ 记录您使用 io.vertx.core.spi.cluster.AsyncMultiMap 接口创建的所有 AsyncMultiMap/io.vertx/locks/ 记录分布式锁信息。/io.vertx/counters/ 记录分布式计数信息。

使用此集群管理器

如果您从命令行使用 Vert.x,则与此集群管理器对应的 jar(它将被命名为 vertx-zookeeper-5.0.1.jar)应位于 Vert.x 安装的 lib 目录中。

如果您想在 Vert.x Maven 或 Gradle 项目中使用此集群管理器进行集群,只需在您的项目中添加对以下 artifact 的依赖:io.vertx:vertx-zookeeper:${version}

如果 JAR 包如上所示位于您的类路径中,Vert.x 将自动检测并使用它作为集群管理器。请确保您的类路径中没有其他集群管理器,否则 Vert.x 可能会选择错误的管理器。

如果您嵌入 Vert.x,也可以在创建 Vert.x 实例时通过在选项中指定来以编程方式指定集群管理器,例如

ClusterManager mgr = new ZookeeperClusterManager();
Vertx.builder()
  .withClusterManager(mgr)
  .buildClustered().onComplete(res -> {
  if (res.succeeded()) {
    Vertx vertx = res.result();
  } else {
    // failed!
  }
});

配置此集群管理器

通常,集群管理器由一个文件 default-zookeeper.json 配置,该文件打包在 jar 中。

如果您想覆盖此配置,您可以在类路径中提供一个名为 zookeeper.json 的文件,它将被使用。如果您想将 zookeeper.json 文件嵌入到胖 jar 中,它必须位于胖 jar 的根目录。如果它是外部文件,则必须将包含该文件的**目录**添加到类路径中。例如,如果您正在使用 Vert.x 的 *launcher* 类,类路径增强可以按如下方式完成:

# If the zookeeper.json is in the current directory:
java -jar ... -cp . -cluster
vertx run MyVerticle -cp . -cluster

# If the zookeeper.json is in the conf directory
java -jar ... -cp conf -cluster

覆盖配置的另一种方法是通过提供带有位置的系统属性 vertx.zookeeper.conf

# Use a cluster configuration located in an external file
java -Dvertx.zookeeper.config=./config/my-zookeeper-conf.json -jar ... -cluster

# Or use a custom configuration from the classpath
java -Dvertx.zookeeper.config=classpath:my/package/config/my-cluster-config.json -jar ... -cluster

vertx.zookeeper.config 系统属性(如果存在)会覆盖类路径中的任何 zookeeper.json,但如果从此系统属性加载失败,则会回退到 zookeeper.json 或 Zookeeper 默认配置。

配置文件在 `default-zookeeper.json` 的注释中详细描述。

如果嵌入,您也可以通过编程方式指定配置

JsonObject zkConfig = new JsonObject();
zkConfig.put("zookeeperHosts", "127.0.0.1");
zkConfig.put("rootPath", "io.vertx");
zkConfig.put("retry", new JsonObject()
    .put("initialSleepTime", 3000)
    .put("maxTimes", 3));


ClusterManager mgr = new ZookeeperClusterManager(zkConfig);

Vertx.builder()
  .withClusterManager(mgr)
  .buildClustered().onComplete(res -> {
  if (res.succeeded()) {
    Vertx vertx = res.result();
  } else {
    // failed!
  }
});

重试策略可以在 json 配置中指定,如下所示:

{
  "retry":{
    "policy": "exponential_backoff"
  }
}

策略的可能值是:

  • exponential_backoff (默认)

  • bounded_exponential_backoff

  • one_time

  • n_times

  • forever

  • until_elapsed

您还可以使用 vertx.zookeeper.hosts 系统属性配置 Zookeeper 主机。

启用日志记录

在对 Zookeeper 集群问题进行故障排除时,获取一些来自 Zookeeper 的日志输出通常很有用,以查看它是否正确形成集群。您可以通过在类路径中添加一个名为 vertx-default-jul-logging.properties 的文件来完成此操作(当使用默认 JUL 日志记录时)。这是一个标准的 java.util.logging (JUL) 配置文件。在其中设置:

org.apache.zookeeper.level=INFO

并且

java.util.logging.ConsoleHandler.level=INFO
java.util.logging.FileHandler.level=INFO