java - Vertx.io 集群和服务发现

标签 java vert.x vertx-verticle

我正在玩 vertx.io,它看起来很棒。现在我建立了一个由三个 Verticle 组成的集群(三个简单的 Java 主 fat jar )。一个 Verticle 公开了一个 Web 界面(一个糟糕的休息 API),另外两个只是通过 vertx.io 的服务发现机制知道 Web Verticle 它们是启动还是关闭。 这是我的(相关部分)简单的“非网络”verticle:

public class FileReader extends AbstractVerticle {

  private ServiceDiscovery discovery;
  private Logger log = LogManager.getLogger(getClass());
  private Record record;

  @Override
  public void start(Future<Void> startFuture) throws Exception {
    record = EventBusService.createRecord(getServiceName(), getServiceAddress(), getClass());
    setUpRecord(record);
    discovery = ServiceDiscovery.create(vertx);
    discovery.publish(record, h -> {
        if (h.succeeded()) {
            log.info("Record published.");
        } else {
            log.info("Record not published.", h.cause());
        }
    });
    startFuture.complete();
  }
  ...
  @Override
  public void stop(Future<Void> stopFuture) throws Exception {
    log.info("Stopping verticle.");
    discovery.unpublish(record.getRegistration(), h -> {
        if (h.succeeded()) {
            log.info("Service unpublished.");
            stopFuture.complete();
        } else {
            log.error(h.cause());
            stopFuture.fail(h.cause());
        }
    });
  }
}

下面是我如何部署两个“非网络”verticles 之一:

public class FileReaderApp {

private static Logger log = LogManager.getLogger(FileReaderApp.class);
private static String id;

  public static void main(String[] args) {
    ClusterManager cMgr = new HazelcastClusterManager();
    VertxOptions vOpt = new VertxOptions(new JsonObject());
    vOpt.setClusterManager(cMgr);
    Vertx.clusteredVertx(vOpt, ch -> {
        if (ch.succeeded()) {
            log.info("Deploying file reader.");
            Vertx vertx = ch.result();
            vertx.deployVerticle(new FileReader(), h -> {
                if (h.succeeded()) {
                    id = h.result();
                } else {
                    log.error(h.cause());
                }
            });
        } else {
            log.error(ch.cause());
        }
    });

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            log.info("Undeploying " + id);
            Vertx.vertx().undeploy(id, h -> {
                if (h.succeeded()) {
                    log.info("undeployed.");
                } else {
                    log.error(h.cause());
                }
            });
        }
    });
  }
}

当“非网络”verticle 启动时,“web”verticle 会被正确通知。但是当“非网络”Verticle 关闭时,我按下键盘 Ctrl-C,我得到了这个错误,“Web”Verticle 仍然认为每个人都在:

2017-12-01 09:08:27 INFO  FileReader:31 - Undeploying 82a8f5c2-e6a2-4fc3-84ff-4bb095b5dc43
Exception in thread "Thread-3" java.lang.IllegalStateException: Shutdown in progress
at java.lang.ApplicationShutdownHooks.add(ApplicationShutdownHooks.java:66)
at java.lang.Runtime.addShutdownHook(Runtime.java:211)
at io.vertx.core.impl.FileResolver.setupCacheDir(FileResolver.java:310)
at io.vertx.core.impl.FileResolver.<init>(FileResolver.java:92)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:185)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:144)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:140)
at io.vertx.core.impl.VertxFactoryImpl.vertx(VertxFactoryImpl.java:34)
at io.vertx.core.Vertx.vertx(Vertx.java:82)
at edu.foo.app.FileReaderApp$1.run(FileReaderApp.java:32)

我不完全明白发生了什么。应用程序在取消部署 Verticle 时关闭?如何解决这个问题?什么是 vertx.io 方法?

最佳答案

有两个问题

  1. 您应该使用集群 Vert.x 实例取消部署 Verticle,而不仅仅是任何实例
  2. undeploy 是非阻塞操作,因此关闭 Hook 线程必须等待完成。

修改后的版本:

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        log.info("Undeploying " + id);
        CountDownLatch latch = new CountDownLatch(1);
        theClusteredVertxInstance.undeploy(id, h -> {
            if (h.succeeded()) {
                log.info("undeployed.");

            } else {
                log.error(h.cause());
            }
            latch.countDown();
        });
        try {
            latch.await(5, TimeUnit.SECONDS);
        } catch(Exception ignored) {
        }
    }
});

关于java - Vertx.io 集群和服务发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47589677/

相关文章:

java - 如何使用黑莓连接到同一网络上的对等计算机

Java行为通知频率

java - 如何在 Vert.x (java) 中使用 Jackson 流式传输 JSON 结果

java - 使用带有 JsonParser 的 NetClient 连接到服务器仅解析第一条消息

java - Vert.x - Verticle 和 Services 之间的差异

java - 如何使用 vert.x 在工作线程上应用并发处理

java - JFrame#setLayout(LayoutManager) 不起作用。强制执行 getContentPane().setLayout(LayoutManager)

java - 从 FirebaseRecyclerAdapter 获取文档 ID 并将值传递给新页面

java - 从命令行运行 Verticle 时找不到包

java - 如何更改spring mockmvc的http端口