Vert.x Multidocker AWS 中的 Hazelcast

Vert.x Hazelcast in Multidocker AWS

我尝试通过多个 Docker 容器在 EC2 节点上 运行 多个 Vert.x 实例。

容器A: 端口转发:5071 -> 5071 本地IP:172.17.0.4

容器B: 端口转发:5072 -> 5072 本地IP:172.17.0.5

容器 C: 端口转发:5073 -> 5073 本地IP:172.17.0.6

我使用 Hazelcast Amazon EC2 安装程序,但这不起作用,因为节点本身只有一个 Public IP(在 Hazelcastsetup 中设置)并且不可能添加端口。

如何在不同端口上通过 aws 中的 hazelcast 运行 多个顶点(也许这个不同的端口解决方案不是最好的解决方案)。

谢谢 马塞尔

P.s.: 我尝试通过 tcp-ip 设置添加节点,但不允许混合 AWS 和 tcp 连接。

P.p.s:我不能也不想在 AWS ElasticBeanstalk 中使用“--net=host”

看起来像这样:https://github.com/hazelcast/hazelcast/issues/4537

更新:

我的 HC 配置

    JsonObject amazonConfig = clusterConfig.getJsonObject("aws");

    String publicIp = null;
    String privateIp = null;
    String localIp = InetAddress.getLocalHost().getHostAddress();

    logger.info("Found local IP: " + localIp);

    try {
        publicIp = doHttpUrlConnectionAction("http://169.254.169.254/latest/meta-data/public-ipv4");

        logger.info("Found public IP: " + publicIp);

        privateIp = doHttpUrlConnectionAction("http://169.254.169.254/latest/meta-data/local-ipv4");
        logger.info("Found private IP: " + privateIp);

    } catch (IOException | InterruptedException e) {
        logger.fatal("Cannot detect public cloud ip");
        throw e;
    }

    logger.info("AWS Cluster config loaded");

    hazelcastConfig.getNetworkConfig().setPublicAddress(privateIp);
    hazelcastConfig.getNetworkConfig().setPortAutoIncrement(false);

    if (amazonConfig.containsKey("hazelcastPort")) {
        logger.info("Use port " + amazonConfig.getString("hazelcastPort") + " for hazelcast");

        hazelcastConfig.getNetworkConfig()
                .setPublicAddress(privateIp + ":" + amazonConfig.getString("hazelcastPort"));

        hazelcastConfig.getNetworkConfig().setPort(Integer.valueOf(amazonConfig.getString("hazelcastPort")));
    }

    // hazelcastConfig.setProperty("hazelcast.local.localAddress",
    // localIp);

    hazelcastConfig.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
    hazelcastConfig.getNetworkConfig().getJoin().getAwsConfig().setEnabled(true);

    // hazelcastConfig.getNetworkConfig().getInterfaces().setEnabled(true).addInterface(localIp);

    if (amazonConfig.containsKey("region")) {
        hazelcastConfig.getNetworkConfig().getJoin().getAwsConfig().setRegion(amazonConfig.getString("region"));
    }
    if (amazonConfig.containsKey("accessKey")) {
        hazelcastConfig.getNetworkConfig().getJoin().getAwsConfig()
                .setAccessKey(amazonConfig.getString("accessKey"));
    }
    if (amazonConfig.containsKey("secretKey")) {
        hazelcastConfig.getNetworkConfig().getJoin().getAwsConfig()
                .setSecretKey(amazonConfig.getString("secretKey"));
    }

    try {
        String hazelcastGroup = System.getenv("HAZELCASTGROUP");

        logger.info("Join Hazelcast Nodes with Tag HAZELCASTGROUP and Value " + hazelcastGroup);

        hazelcastConfig.getNetworkConfig().getJoin().getAwsConfig().setTagKey("HAZELCASTGROUP");
        hazelcastConfig.getNetworkConfig().getJoin().getAwsConfig().setTagValue(hazelcastGroup);

    } catch (Exception e) {
        logger.error("Cannot detect hazelcastgroup: " + e.getMessage(), e);

        throw e;
    }

    mgr = new HazelcastClusterManager(hazelcastConfig);

    vertxOptions = new VertxOptions().setClusterManager(mgr).setClustered(true);

解决方案

// privateIp = doHttpUrlConnectionAction("http://169.254.169.254/latest/meta-data/local-ipv4");

hazelcastConfig.getNetworkConfig().setPublicAddress(privateIp);

不要禁用 setPortAutoIncrement

对于第一个 Docker 图像,您应该通过

将端口设置为 5701
hazelcastConfig.getNetworkConfig().setPort(5701);

第二个 Docker 图片 - 5702 依此类推

您不需要 link Docker 容器。只需为每个图像做一个端口映射。

为此端口创建一个安全组,以便其他节点可以访问这些端口。

这是我的建议。如果不能解决问题,请 post HZ 日志语句。

  1. 取消注释为 localAddress 添加 属性 的行。 hazelcastConfig.setProperty("hazelcast.local.localAddress", localIp);
  2. 明确禁用 tcp-ip 配置。
  3. 第二次去掉Public地址的设置

    hazelcastConfig.getNetworkConfig().setPublicAddress(privateIp);
    hazelcastConfig.getNetworkConfig().setPortAutoIncrement(false);
    
    if (amazonConfig.containsKey("hazelcastPort")) {
         logger.info("Use port " + amazonConfig.getString("hazelcastPort") + " for hazelcast");
         hazelcastConfig.getNetworkConfig().setPort(Integer.valueOf(amazonConfig.getString("hazelcastPort")));
    }
    
  4. 如果可以,请尝试使用默认端口本身。正如您在评论中指出的那样,HZ 不支持自定义端口存在一个问题。此外,AWSClient 规范不允许指定自定义端口,它们倾向于使用默认端口 5701、5702、5703。这是我几个月前创建的增强请求。 https://github.com/hazelcast/hazelcast-aws/issues/3

  5. 还要确保 docker 容器能够相互通信。