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 日志语句。
- 取消注释为 localAddress 添加 属性 的行。
hazelcastConfig.setProperty("hazelcast.local.localAddress", localIp);
- 明确禁用 tcp-ip 配置。
第二次去掉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")));
}
如果可以,请尝试使用默认端口本身。正如您在评论中指出的那样,HZ 不支持自定义端口存在一个问题。此外,AWSClient 规范不允许指定自定义端口,它们倾向于使用默认端口 5701、5702、5703。这是我几个月前创建的增强请求。 https://github.com/hazelcast/hazelcast-aws/issues/3
还要确保 docker 容器能够相互通信。
我尝试通过多个 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 图像,您应该通过
将端口设置为 5701hazelcastConfig.getNetworkConfig().setPort(5701);
第二个 Docker 图片 - 5702 依此类推
您不需要 link Docker 容器。只需为每个图像做一个端口映射。
为此端口创建一个安全组,以便其他节点可以访问这些端口。
这是我的建议。如果不能解决问题,请 post HZ 日志语句。
- 取消注释为 localAddress 添加 属性 的行。
hazelcastConfig.setProperty("hazelcast.local.localAddress", localIp);
- 明确禁用 tcp-ip 配置。
第二次去掉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"))); }
如果可以,请尝试使用默认端口本身。正如您在评论中指出的那样,HZ 不支持自定义端口存在一个问题。此外,AWSClient 规范不允许指定自定义端口,它们倾向于使用默认端口 5701、5702、5703。这是我几个月前创建的增强请求。 https://github.com/hazelcast/hazelcast-aws/issues/3
还要确保 docker 容器能够相互通信。