Hazelcast 领导者选举集群可以在没有 hz 运算符的 OpenShift 容器中工作吗?

问题描述 投票:0回答:1

我正在尝试部署 Java SpringBoot 微服务以在 OpenShift 容器上使用领导者选举。我无需配置即可使其在本地工作。我尝试了2个节点(在相同的IP,不同的端口上)。我没有做任何特殊配置来让它工作。

但是当我将代码部署到 OpenShift Container 并将其部署到 2 个节点时,集群不起作用。节点似乎无法找到彼此(它们位于不同的 IP,相同的端口)。所以它是裂脑的。

我查找了如何执行此操作,并找到了这些说明来使用和安装 hazelcast-operators(Hazelcast 平台操作员)以使其正常工作,但在我的特定环境中,我们不允许安装此类软件包。

我有什么办法可以完成这项工作,而不需要安装 hazelcast 运算符、RBAC 规则,或者不需要对 OpenShift 环境设置进行任何操作(我在一个非常受限的 OpenShift 环境中工作)?

是否有任何编程或 YAML 配置(在应用程序级别)可以从我的代码中部署以使其正常工作?

我尝试部署我的微服务。这基本上就是我的代码:

@Component
public class Runner implements CommandLineRunner, MembershipListener {
    private static final Logger logger = Logger.getLogger(Runner.class.getName());
...
    private String leaderAddress;
    private HazelcastInstance hazelcastInstance;
...    
    @Autowired
    private CSPRabbitMQConfig rabbitMQConfiguration;

    public Runner(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }
    @Override
    public void run(String... args) throws Exception {      
        hazelcastInstance = Hazelcast.newHazelcastInstance(/* hazelcastConfig */);
        hazelcastInstance.getCluster().addMembershipListener(this);
        
        logger.info("Members: "+ hazelcastInstance.getCluster().getMembers().size());
        leaderAddress = hazelcastInstance.getCluster().getMembers().iterator().next().getSocketAddress().toString();
        logger.info("Current leader address: " + leaderAddress);
...
    // Leader should be the only process to start the subscriptions
    if (amITheLeader()) {
        // TODO: need to verify this works in a multi-host environment.
        // This node is the leader, do leader-specific tasks here
...
        }
...
    }
    ...
    public boolean amITheLeader() {
        logger.info("> amITheLeader() - cluster size: " + hazelcastInstance.getCluster().getMembers().size());
        return hazelcastInstance.getCluster().getLocalMember().getSocketAddress().toString().equals(leaderAddress);
    }

    @Override
    public void memberAdded(MembershipEvent membershipEvent) {
        if (membershipEvent.getMember().getSocketAddress().toString().compareTo(leaderAddress) < 0) {
            // A new member has joined that has an older address, it becomes the new leader
            leaderAddress = membershipEvent.getMember().getSocketAddress().toString();
            if (amITheLeader()) {
                // This node is the new leader, do leader-specific tasks here
            }
        }
    }

    @Override
    public void memberRemoved(MembershipEvent membershipEvent) {
        if (membershipEvent.getMember().getSocketAddress().toString().equals(leaderAddress)) {
            // The leader has left the cluster, a new leader will be elected
            leaderAddress = hazelcastInstance.getCluster().getMembers().iterator().next().getSocketAddress().toString();
            if (amITheLeader()) {
                // This node is the new leader, do leader-specific tasks here
            }                  
        }
    }

我包含了这个 Maven 依赖项:

        <dependency>
            <groupId>com.hazelcast</groupId>
            <artifactId>hazelcast-spring</artifactId>
        </dependency>

也许还有另一种方法可以对此进行编码,或者也许我正在以过时的方式进行此操作?

这对于在同一 IP 地址(不同端口)上运行的应用程序的多个实例在本地运行良好 - 有时,有时,节点无法找到彼此。

我原以为部署到 OpenShift 后它会自动工作,但是一旦我这样做了,我发现节点无法找到彼此,因此集群无法工作,这不允许领导者选举正常工作。

spring-boot openshift hazelcast leader-election
1个回答
0
投票

在 DNS 查找模式下使用 Kubernetes 可能正是您所需要的。

基本思想是为 Kubernetes 集群中的微服务创建一个 Headless Service。它基本上是一个指向所有服务实例的 DNS 条目。然后,您在 Hazelcast 加入配置中配置此 DNS 名称,每个实例都会找到所有其他实例。该文档提供了有关此类 Kubernetes 服务的外观以及如何使用 YAML 或 Java 调整 Hazelcast 配置的详细信息。

该文档还提供了此方法的优点和缺点的列表。我的印象是这种 DNS Lookup 模式在生产中使用较少,但似乎仍然受支持。

© www.soinside.com 2019 - 2024. All rights reserved.