【问题标题】:Is it possible to start a zookeeper server instance in process, say for unit tests?是否可以在进程中启动 Zookeeper 服务器实例,例如用于单元测试?
【发布时间】:2012-03-06 08:41:23
【问题描述】:

调用 org.apache.zookeeper.server.quorum.QuorumPeerMain.main() 不起作用。

【问题讨论】:

  • 此外,curator 框架附带了一个内存中的 zookeeper 实现,用于单元测试
  • curator 确实附带了一个测试 Zookeeper,但它不在内存中。它将数据存储在磁盘上的临时目录中。

标签: java unit-testing apache-zookeeper


【解决方案1】:

你可以使用这样的东西。

int clientPort = 21818; // none-standard
int numConnections = 5000;
int tickTime = 2000;
String dataDirectory = System.getProperty("java.io.tmpdir");

File dir = new File(dataDirectory, "zookeeper").getAbsoluteFile();

ZooKeeperServer server = new ZooKeeperServer(dir, dir, tickTime);
NIOServerCnxn.Factory standaloneServerFactory = new NIOServerCnxn.Factory(new InetSocketAddress(clientPort), numConnections);

standaloneServerFactory.startup(server); // start the server.

要关闭它,只需致电standaloneServerFactory.shutdown()

【讨论】:

    【解决方案2】:

    要启动ZooKeeper,您必须执行ZooKeeperServerMain 类。

    您可以使用以下代码以嵌入模式启动ZooKeeper

    Properties startupProperties = ...
    
    QuorumPeerConfig quorumConfiguration = new QuorumPeerConfig();
    try {
        quorumConfiguration.parseProperties(startupProperties);
    } catch(Exception e) {
        throw new RuntimeException(e);
    }
    
    zooKeeperServer = new ZooKeeperServerMain();
    final ServerConfig configuration = new ServerConfig();
    configuration.readFrom(quorumConfiguration);
    
    new Thread() {
        public void run() {
            try {
                zooKeeperServer.runFromConfig(configuration);
            } catch (IOException e) {
                log.error("ZooKeeper Failed", e);
            }
        }
    }.start();
    

    【讨论】:

    • 这是单元测试的方式。使用 QuorumPeerMain 仅适用于多服务器(集群)Zookeeper。
    • 这在 BeforeClass 的上下文中很有用,但在测试之间关闭它(例如清理节点)并非易事——我放弃并切换到基于 Curator 的解决方案. (After 中的 thread.stop/interrupt 会停止 JUnitRunner)
    • 您知道如何在 C++ 项目中进行设置吗?
    • serup,Zookeeper 是一个 Java 进程
    • 你好,你能举一个启动属性设置的例子吗?
    【解决方案3】:
    ServerConfig config = new ServerConfig();
    config.parse(new String[] {port, dir});
    ZooKeeperServerMain zk = new ZooKeeperServerMain();
    zk.runFromConfig(config);
    

    【讨论】:

    • 你不能以这种方式运行zookeeper服务器,因为它会阻塞下面的代码,即zk.runFromConfig(config)之后的代码;从被执行。
    【解决方案4】:

    1 的答案的基础上,添加使用临时端口(由zkPort 显示)并更新为最新的ZK API:

    int tickTime = 2000;
    int numConnections = 5000;
    String dataDirectory = System.getProperty("java.io.tmpdir");
    
    File dir = new File(dataDirectory, "zookeeper").getAbsoluteFile();
    
    ZooKeeperServer server = new ZooKeeperServer(dir, dir, tickTime);
    standaloneServerFactory = ServerCnxnFactory.createFactory(0, numConnections);
    int zkPort = standaloneServerFactory.getLocalPort();
    
    standaloneServerFactory.startup(server);
    

    【讨论】:

    • 您可能无法以这种方式启动zoo keeper server,因为它会阻止所有后续代码在standaloneServerFactory.startup(server)之后执行;
    【解决方案5】:

    Netfix 开源了Curator 一个框架,让 Zookeeper 的使用更加方便。它内置了测试服务器类。只需将此 test 依赖项添加到您的项目描述符中,无论是 maven、gradle 还是其他:

    org.apache.curator:curator-framework:4.0.1
    org.apache.curator:curator-test:4.0.1
    

    这里是测试要点。

    TestingServer zkTestServer;
    CuratorFramework cli;
    
    @Before
    public void startZookeeper() throws Exception {
        zkTestServer = new TestingServer(2181);
        cli = CuratorFrameworkFactory.newClient(zkTestServer.getConnectString(), new RetryOneTime(2000));
        cli.start();
    }
    
    @After
    public void stopZookeeper() throws IOException {
        cli.close();
        zkTestServer.stop();
    }
    

    使用cli 创建任何测试数据都非常容易(需要curator-framework 依赖项)。

    cli.create()
       .creatingParentsIfNeeded()
       .forPath("/a1", "testvalue".getBytes("UTF-8"));
    

    【讨论】:

    • 对我来说,如果没有使用 Curator 版本 2.10.0 的 cli.start(),它就无法工作
    • @MichaelBöckling 谢谢!我还需要先打电话给cli.start() 然后它才开始工作
    • 嗨@gertas。咳咳,是否可以使用 Curator 监控一组 zookeeper,如果其中一个 zookeeper 实例出现故障,是否可以使用它自动重启它?
    【解决方案6】:

    GeoffBourne 答案的更新版本。

        int clientPort = 2199; // not standard
        int numConnections = 5000;
        int tickTime = 2000;
        String dataDirectory = System.getProperty("java.io.tmpdir");
    
        File dir = new File(dataDirectory, "zookeeper").getAbsoluteFile();
    
        ZooKeeperServer server = new ZooKeeperServer(dir, dir, tickTime);
        ServerCnxnFactory factory = new NIOServerCnxnFactory();
        factory.configure(new InetSocketAddress(clientPort), numConnections);
    
        factory.startup(server); // start the server.
    
        // ...shutdown some time later
        factory.shutdown();
    

    【讨论】:

      猜你喜欢
      • 2017-06-25
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      • 2014-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多