Search in sources :

Example 6 with HeartBeatStrategy

use of io.mycat.replica.heartbeat.HeartBeatStrategy in project Mycat2 by MyCATApache.

the class MHATest method testMasterBroken.

@Test
public void testMasterBroken() {
    ClusterConfig clusterConfig = CreateClusterHint.createConfig("c0", Arrays.asList("dsw1", "dsw2"), Arrays.asList("dsr1"));
    TimerConfig timerConfig = new TimerConfig();
    timerConfig.setTimeUnit(TimeUnit.SECONDS.name());
    timerConfig.setPeriod(1);
    timerConfig.setInitialDelay(0);
    clusterConfig.setTimer(timerConfig);
    clusterConfig.setClusterType(ReplicaType.MHA.name());
    HashMap<String, DatasourceConfig> map = new HashMap<>();
    map.put("dsw1", CreateDataSourceHint.createConfig("dsw1", DB1));
    map.put("dsw2", CreateDataSourceHint.createConfig("dsw2", DB2));
    map.put("dsr1", CreateDataSourceHint.createConfig("dsr1", DB2));
    LinkedList<Runnable> runnables = new LinkedList<>();
    ReplicaSelectorManager manager = ReplicaSelectorRuntime.create(Arrays.asList(clusterConfig), map, new LoadBalanceManager(), name -> 0, (command, initialDelay, period, unit) -> {
        runnables.add(command);
        return () -> {
        };
    });
    manager.start();
    manager.putHeartFlow("c0", "dsw1", makeBroken());
    manager.putHeartFlow("c0", "dsw2", checkMHA(false, 0));
    manager.putHeartFlow("c0", "dsr1", checkMHA(false, 0));
    // 模拟第一主节点无法连接
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            List<String> c0 = state.get("c0");
            Assert.assertEquals("[dsw2]", c0.toString());
        }
    }));
    // 三次错误后触发主从切换
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
        checkALlRight(manager);
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
        PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw1");
        Assert.assertFalse(dsw1.asSelectRead());
        Assert.assertFalse(dsw1.isAlive());
        PhysicsInstance dsw2 = manager.getPhysicsInstanceByName("dsw2");
        Assert.assertTrue(dsw2.asSelectRead());
        Assert.assertTrue(dsw2.isAlive());
        PhysicsInstance dsr1 = manager.getPhysicsInstanceByName("dsr1");
        Assert.assertTrue(dsr1.asSelectRead());
        Assert.assertTrue(dsr1.isAlive());
    }
    // 触发切换
    manager.putHeartFlow("c0", "dsw2", checkMHA(true, 0));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    // 测试已经切换
    Set<String> balanceTargets = new HashSet<>();
    test(() -> {
        balanceTargets.add(manager.getDatasourceNameByReplicaName("c0", false, null));
        return false;
    });
    Assert.assertTrue(balanceTargets.size() <= 2);
    Assert.assertFalse(balanceTargets.contains("dsw1"));
    Set<String> masterTargets = new HashSet<>();
    test(() -> {
        masterTargets.add(manager.getDatasourceNameByReplicaName("c0", true, null));
        return false;
    });
    // todo check
    Assert.assertEquals(1, masterTargets.size());
    Assert.assertTrue(masterTargets.contains("dsw2"));
    manager.putHeartFlow("c0", "dsw2", checkMHA(true, 0));
    manager.putHeartFlow("c0", "dsw1", checkMHA(false, 0));
    manager.putHeartFlow("c0", "dsr1", checkMHA(false, 0));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    checkALlRight(manager);
    // 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
    manager.putHeartFlow("c0", "dsw2", makeBroken());
    manager.putHeartFlow("c0", "dsw1", checkMHA(false, 0));
    manager.putHeartFlow("c0", "dsr1", checkMHA(false, 0));
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            List<String> c0 = state.get("c0");
            Assert.assertEquals("[dsw1]", c0.toString());
        }
    }));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    {
        PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw2");
        Assert.assertFalse(dsw1.asSelectRead());
        Assert.assertFalse(dsw1.isAlive());
        PhysicsInstance dsw2 = manager.getPhysicsInstanceByName("dsw1");
        Assert.assertTrue(dsw2.asSelectRead());
        Assert.assertTrue(dsw2.isAlive());
        PhysicsInstance dsr1 = manager.getPhysicsInstanceByName("dsr1");
        Assert.assertTrue(dsr1.asSelectRead());
        Assert.assertTrue(dsr1.isAlive());
    }
    // 测试最小切换周期
    Consumer<HeartBeatStrategy> consumer = new Consumer<HeartBeatStrategy>() {

        int count = 0;

        @Override
        public void accept(HeartBeatStrategy heartBeatStrategy) {
            if (ThreadLocalRandom.current().nextBoolean()) {
                makeBroken().accept(heartBeatStrategy);
            } else {
                checkMasterSlave().accept(heartBeatStrategy);
            }
            count++;
        }
    };
    manager.putHeartFlow("c0", "dsw2", consumer);
    manager.putHeartFlow("c0", "dsw1", consumer);
    manager.putHeartFlow("c0", "dsr1", consumer);
    AtomicInteger switchCounter = new AtomicInteger();
    MetaClusterCurrent.register(Maps.of(ConfigReporter.class, new ConfigReporter() {

        @Override
        public void reportReplica(Map<String, List<String>> state) {
            switchCounter.getAndIncrement();
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
            }
        }
    }));
    for (int i = 0; i < 1000; i++) {
        for (Runnable runnable : runnables) {
            runnable.run();
        }
    }
    Assert.assertTrue(switchCounter.get() < 100);
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) CreateDataSourceHint(io.mycat.hint.CreateDataSourceHint) CreateClusterHint(io.mycat.hint.CreateClusterHint) MHAHeartBeatStrategy(io.mycat.replica.heartbeat.strategy.MHAHeartBeatStrategy) HeartBeatStrategy(io.mycat.replica.heartbeat.HeartBeatStrategy) DatasourceConfig(io.mycat.config.DatasourceConfig) Consumer(java.util.function.Consumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConfigReporter(io.mycat.ConfigReporter) ClusterConfig(io.mycat.config.ClusterConfig) Test(org.junit.Test)

Aggregations

ConfigReporter (io.mycat.ConfigReporter)6 ClusterConfig (io.mycat.config.ClusterConfig)6 DatasourceConfig (io.mycat.config.DatasourceConfig)6 TimerConfig (io.mycat.config.TimerConfig)6 CreateClusterHint (io.mycat.hint.CreateClusterHint)6 CreateDataSourceHint (io.mycat.hint.CreateDataSourceHint)6 LoadBalanceManager (io.mycat.plug.loadBalance.LoadBalanceManager)6 HeartBeatStrategy (io.mycat.replica.heartbeat.HeartBeatStrategy)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 Consumer (java.util.function.Consumer)6 Test (org.junit.Test)6 MGRHeartBeatStrategy (io.mycat.replica.heartbeat.strategy.MGRHeartBeatStrategy)1 MHAHeartBeatStrategy (io.mycat.replica.heartbeat.strategy.MHAHeartBeatStrategy)1