为了账号安全,请及时绑定邮箱和手机立即绑定

配置 Hazelcast CPSubsystem 重试超时

配置 Hazelcast CPSubsystem 重试超时

Qyouu 2023-06-08 19:26:30
目前我在CPSubsystem.      -----      | I1* | * Leader      -----  ----       ---- | I2 |     | I3 | ----       ---- 当所有实例都启动运行时,所有实例都已注册并相互查看,CPSubsystem一切都按预期工作。以下调用用于在所有实例之间执行分布式锁:getHazelcastInstance().getCpSubsystem().getLock(lockDefinition.getLockEntryName())当其中两个实例死亡时,我注意到一个问题,并且没有领导者或其他实例可用于执行领导者选举:      -----      | XXX | * DEAD      -----  ----       ----- | I2 |     | XXX | * DEAD ----       ----- 正在运行的实例然后尝试获取分布式锁,但是请求冻结执行该getLock方法,导致请求排队几分钟(当实例成为子系统中的唯一实例时需要配置超时)。我还注意到以下日志被永久打印:2019-08-16 10:56:21.697  WARN 1337 --- [ration.thread-1] Impl$LeaderFailureDetectionTask(default) : [127.0.0.1]:5702 [dev] [3.12.1] We are FOLLOWER and there is no current leader. Will start new election round...2019-08-16 10:56:23.737  WARN 1337 --- [cached.thread-8] c.h.nio.tcp.TcpIpConnectionErrorHandler  : [127.0.0.1]:5702 [dev] [3.12.1] Removing connection to endpoint [127.0.0.1]:5701 Cause => java.net.SocketException {Connection refused to address /127.0.0.1:5701}, Error-Count: 1062019-08-16 10:56:23.927  WARN 1337 --- [ration.thread-1] Impl$LeaderFailureDetectionTask(default) : [127.0.0.1]:5702 [dev] [3.12.1] We are FOLLOWER and there is no current leader. Will start new election round...有没有办法识别实例现在是单独运行的,如果是这样,在获取新锁的过程中不要阻塞应用程序?我一直在寻找某种机制来不以任何方式阻止应用程序的流程,即使应用程序单独运行我也会使用常规而j.u.c.l.ReentrantLock不是FencedLock.
查看完整描述

2 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

CP 子系统旨在在没有足够的成员可用于首先形成 CP 子系统时阻止对属于 CP 子系统系列的数据结构的所有操作。此属性由CPSubsystemConfig.setCPMemberCount(int)

hazelcastInstance.getCPSubsystem().getCPSubsystemManagementService().getCPMembers()将为您提供集群中的 CP 成员。

要确定集群成员计数,您可以hazelcastInstance.getCluster().getMembers()对成员加入或离开事件使用和/或使用 MembershipListener。


查看完整回答
反对 回复 2023-06-08
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

经过几天的测试,我得出以下结论:

  1. 但是CPSubsystem需要至少三个模块才能开始工作,运行两个实例就可以了

  2. 在我提出的最灾难性的可能场景中(只有一个实例在运行),没有什么可做的,你的环境可能有一个 ruff 时间,需要某种干预或关注来解决这个中断

我决定在这种情况下阻止请求被满足,以保持模块之间所有操作的一致性。

所以方法如下:

try {

    if( !hz.isCpInstanceAvailable() ) {

        throw new HazelcastUnavailableException("CPSubsystem is not available");

    }

    ... acquires the lock ...

} catch (HazelcastUnavailableException e) {

    LOG.error("Error retrieving Hazelcast Distributed Lock :( Please check the CPSubsystem health among all instances", e);

    throw e;

}

该方法isCpInstanceAvailable将执行三个验证:

  1. 如果当前应用程序注册在CPSubsystem

  2. 如果CPSubsystem

  3. 如果在CPSubsystem

所以这是解决方案:


protected boolean isCpInstanceAvailable() {

    try {

        return getCPLocalMember() != null && getCPMembers().get(getMemberValidationTimeout(), TimeUnit.SECONDS).size() > ONE_MEMBER;

    } catch (InterruptedException | ExecutionException | TimeoutException e) {

        LOG.error("Issue retrieving CP Members", e);

    }


    return false;

}


protected ICompletableFuture<Collection<CPMember>> getCPMembers() {

    return Optional.ofNullable(getCPSubsystemManagementService().getCPMembers()).orElseThrow(

            () -> new HazelcastUnavailableException("CP Members not available"));

}


protected CPMember getCPLocalMember() {

    return getCPSubsystemManagementService().getLocalCPMember();

}

问题来了,简单地调用getCPMembers().get()会导致我遇到的长时间暂停(默认超时)。


所以我使用了getCPMembers().get(getMemberValidationTimeout(), TimeUnit.SECONDS),如果调用超过预期超时,它将抛出错误。


查看完整回答
反对 回复 2023-06-08
  • 2 回答
  • 0 关注
  • 225 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信