首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何配置Vert.x event bus以跨Docker容器集群工作?

如何配置Vert.x event bus以跨Docker容器集群工作?
EN

Stack Overflow用户
提问于 2016-10-02 08:46:22
回答 3查看 7.2K关注 0票数 6

在我当前的设置中,我使用Hazelcast集群管理器的默认多播选项。当我链接我的容器化Vertx模块的实例时(通过Docker网络链接),我可以看到它们成功地创建了Hazelcast集群。但是,当我尝试从一个模块在事件总线上发布事件时,另一个模块没有反应。我不确定Hazelcast集群中的网络设置如何与事件总线的网络设置相关。

目前,我为我的每个Vert.x模块都有以下编程配置,每个模块都部署在一个docker容器中。

代码语言:javascript
复制
ClusterManager clusterManager = new HazelcastClusterManager();
VertxOptions vertxOptions = new VertxOptions()
            .setClustered(true)
            .setClusterManager(clusterManager);
vertxOptions.setEventBusOptions(new EventBusOptions()
            .setClustered(true)
            .setClusterPublicHost("application"));

Vert.x核心手册指出,我可能必须为事件总线配置clusterPublicHostclusterPublicPort,但我不确定这些与一般网络拓扑结构之间的关系。

EN

回答 3

Stack Overflow用户

发布于 2016-10-03 12:00:05

其中一个答案是https://groups.google.com/d/msg/vertx/_2MzDDowMBM/nFoI_k6GAgAJ

我经常看到这个问题,很多人(包括我自己)在文档中忽略了Event Bus没有使用集群管理器来发送事件总线消息。例如,在您使用Hazelcast作为集群管理器的示例中,您已启动Hazelcast集群并正常通信(因此您的集群管理器是正常的);但是,由于以下一个或多个原因,事件总线无法与其他docker实例通信:

  1. 尝试对另一个节点使用不正确的IP地址(即Docker实例上专用接口的IP,而不是公共映射的IP)
  2. 尝试在Docker未配置为转发的端口上通信(如果未指定动态端口,事件总线将选择一个动态端口)

您需要做的是:

群集主机告诉Vertx其他节点应该用来与每个实例通信的IP地址(使用--

  1. 命令行、setClusterPublicHost VertXOptions或"vertx.cluster.public.host“系统属性options)
  2. Tell Vertx显式指定用于事件总线通信的端口,并确保Docker正在为这些端口转发流量(使用"vertx.cluster.public.port”系统属性、setClusterPublicPort VertXOptions或-vertx.cluster.public.host- Port命令行选项)。在过去,我使用了15701,因为它很容易记住(在Hazelcast端口中只有一个'1‘)。

事件总线仅使用集群管理器来管理其他Vertx实例的IP/端口信息以及消费者/生产者的注册。通信是独立于集群管理器完成的,这就是为什么您可以正确配置集群管理器并进行通信,但仍然没有事件总线通信。

如果两个容器在同一台主机上运行,您可能不需要执行上述两个步骤,但一旦您开始在不同的主机上运行它们,您肯定会执行这两个步骤。

也可能发生的事情是,vert.x使用环回接口,而不是指定vert.x (而不是hazelcast)应该采用的IP来通过eventbus进行通信。这里的问题是,您不知道通过哪个接口进行通信(环回,IP接口,您甚至可能有多个IP接口)。

为了解决这个问题,我曾经写过一个https://github.com/swisspush/vertx-cluster-watchdog/blob/master/src/main/java/org/swisspush/vertx/cluster/ClusterWatchdogRunner.java#L101方法

票数 10
EN

Stack Overflow用户

发布于 2018-03-03 23:13:03

集群管理器运行良好,集群中每个节点(机器/docker容器)上的集群管理器配置必须相同,或者根本不做任何配置(使用集群管理器的默认配置)。

您必须使每个节点上的event bus configuration保持一致,您必须将每个节点上的群集主机设置为此节点本身的IP地址和任意端口号(除非您尝试在同一节点上运行多个Vert.x实例,否则必须为每个Vert.x实例选择不同的端口号)。

代码语言:javascript
复制
VertxOptions options = new VertxOptions()
                .setClustered(true)
                .setClusterHost("192.168.1.12") // node ip
                .setClusterPort(17001) // any arbitrary port but make sure no other Vert.x instances using same port on the same node
                .setClusterManager(clusterManager);

在IP地址为192.168.1.56的另一个节点上,您可以执行以下操作:

代码语言:javascript
复制
VertxOptions options = new VertxOptions()
                .setClustered(true)
                .setClusterHost("192.168.1.56") // other node ip
                .setClusterPort(17001) // it is ok because this is a different node
                .setClusterManager(clusterManager);
票数 3
EN

Stack Overflow用户

发布于 2018-08-12 02:01:46

我发现这个solution非常适合我,下面是我的代码片段(重要的部分是options.setClusterHost()

代码语言:javascript
复制
public class Runner {

    public static void run(Class clazz) {
        VertxOptions options = new VertxOptions();
        try {
            // for docker binding
            String local = InetAddress.getLocalHost().getHostAddress();
            options.setClusterHost(local);
        } catch (UnknownHostException e) { }

        options.setClustered(true);

        Vertx.clusteredVertx(options, res -> {
            if (res.succeeded()) {
                res.result().deployVerticle(clazz.getName());
            } else {
                res.cause().printStackTrace();
            }
        });
    }
}

public class Publisher extends AbstractVerticle {

    public static void main(String[] args) {
        Runner.run(Publisher.class);
    }

    ...
}

不需要定义其他任何东西。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39812848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档