use of io.mycat.replica.heartbeat.HeartBeatStrategy in project Mycat2 by MyCATApache.
the class MGRTest 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.MGR.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", checkMGR(false, 0));
manager.putHeartFlow("c0", "dsr1", checkMGR(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", checkMGR(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;
});
Assert.assertEquals(1, masterTargets.size());
Assert.assertTrue(masterTargets.contains("dsw2"));
manager.putHeartFlow("c0", "dsw2", checkMGR(true, 0));
manager.putHeartFlow("c0", "dsw1", checkMGR(false, 0));
manager.putHeartFlow("c0", "dsr1", checkMGR(false, 0));
for (Runnable runnable : runnables) {
runnable.run();
}
checkALlRight(manager);
// 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
manager.putHeartFlow("c0", "dsw2", makeBroken());
manager.putHeartFlow("c0", "dsw1", checkMGR(false, 0));
manager.putHeartFlow("c0", "dsr1", checkMGR(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);
}
use of io.mycat.replica.heartbeat.HeartBeatStrategy in project Mycat2 by MyCATApache.
the class MasterSlaveTest 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);
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.putHeartFlow("c0", "dsw1", makeBroken());
manager.putHeartFlow("c0", "dsw2", checkMasterSlave());
manager.putHeartFlow("c0", "dsr1", checkMasterSlave());
manager.start();
// 模拟第一主节点无法连接
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());
}
// 测试已经切换
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;
});
Assert.assertEquals(1, masterTargets.size());
Assert.assertTrue(masterTargets.contains("dsw2"));
manager.putHeartFlow("c0", "dsw2", checkMasterSlave());
manager.putHeartFlow("c0", "dsw1", checkMasterSlave());
manager.putHeartFlow("c0", "dsr1", checkMasterSlave());
for (Runnable runnable : runnables) {
runnable.run();
}
checkALlRight(manager);
// 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
manager.putHeartFlow("c0", "dsw2", makeBroken());
manager.putHeartFlow("c0", "dsw1", checkMasterSlave());
manager.putHeartFlow("c0", "dsr1", checkMasterSlave());
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);
}
use of io.mycat.replica.heartbeat.HeartBeatStrategy in project Mycat2 by MyCATApache.
the class GaleraTest 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.GARELA_CLUSTER.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.putHeartFlow("c0", "dsw1", makeBroken());
manager.putHeartFlow("c0", "dsw2", checkGalera());
manager.putHeartFlow("c0", "dsr1", checkGalera());
manager.start();
// 模拟第一主节点无法连接
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());
}
// 测试已经切换
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;
});
Assert.assertEquals(1, masterTargets.size());
Assert.assertTrue(masterTargets.contains("dsw1"));
manager.putHeartFlow("c0", "dsw2", checkGalera());
manager.putHeartFlow("c0", "dsw1", checkGalera());
manager.putHeartFlow("c0", "dsr1", checkGalera());
for (Runnable runnable : runnables) {
runnable.run();
}
checkALlRight(manager);
// 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
manager.putHeartFlow("c0", "dsw2", makeBroken());
manager.putHeartFlow("c0", "dsw1", checkGalera());
manager.putHeartFlow("c0", "dsr1", checkGalera());
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("dsw1");
Assert.assertTrue(dsw1.asSelectRead());
Assert.assertTrue(dsw1.isAlive());
PhysicsInstance dsw2 = manager.getPhysicsInstanceByName("dsw2");
Assert.assertFalse(dsw2.asSelectRead());
Assert.assertFalse(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 {
checkGalera().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);
}
use of io.mycat.replica.heartbeat.HeartBeatStrategy in project Mycat2 by MyCATApache.
the class NoneTest 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.NONE.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 () -> {
};
});
// 模拟第一主节点无法连接
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();
}
{
checkALlRight(manager);
}
for (Runnable runnable : runnables) {
runnable.run();
}
{
PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw1");
Assert.assertTrue(dsw1.asSelectRead());
Assert.assertTrue(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());
}
// 测试已经切换
Set<String> balanceTargets = new HashSet<>();
test(() -> {
balanceTargets.add(manager.getDatasourceNameByReplicaName("c0", false, null));
return false;
});
Assert.assertTrue(balanceTargets.contains("dsw1"));
for (Runnable runnable : runnables) {
runnable.run();
}
{
PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw1");
Assert.assertTrue(dsw1.asSelectRead());
Assert.assertTrue(dsw1.isAlive());
}
// 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
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("dsw1");
Assert.assertTrue(dsw1.asSelectRead());
Assert.assertTrue(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());
}
// 测试最小切换周期
Consumer<HeartBeatStrategy> consumer = new Consumer<HeartBeatStrategy>() {
int count = 0;
@Override
public void accept(HeartBeatStrategy heartBeatStrategy) {
if (ThreadLocalRandom.current().nextBoolean()) {
makeBroken().accept(heartBeatStrategy);
} else {
checkSelect1().accept(heartBeatStrategy);
}
count++;
}
};
manager.putHeartFlow("c0", "dsw1", consumer);
manager.putHeartFlow("c0", "dsw2", 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);
}
use of io.mycat.replica.heartbeat.HeartBeatStrategy in project Mycat2 by MyCATApache.
the class SingleTest 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.SINGLE_NODE.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", checkSelect1());
manager.putHeartFlow("c0", "dsr1", checkSelect1());
// 模拟第一主节点无法连接
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());
}
// 测试已经切换
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;
});
Assert.assertEquals(1, masterTargets.size());
Assert.assertTrue(masterTargets.contains("dsw2"));
manager.putHeartFlow("c0", "dsw2", checkSelect1());
manager.putHeartFlow("c0", "dsw1", checkSelect1());
manager.putHeartFlow("c0", "dsr1", checkSelect1());
for (Runnable runnable : runnables) {
runnable.run();
}
{
PhysicsInstance dsw1 = manager.getPhysicsInstanceByName("dsw1");
Assert.assertTrue(dsw1.asSelectRead());
Assert.assertTrue(dsw1.isAlive());
}
// 切换后又发生短暂的连接损坏,因为新建心跳对象导致切换周期重置,这里不测试最小切换周期
manager.putHeartFlow("c0", "dsw2", makeBroken());
manager.putHeartFlow("c0", "dsw1", checkSelect1());
manager.putHeartFlow("c0", "dsr1", checkSelect1());
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("dsw1");
Assert.assertTrue(dsw1.asSelectRead());
Assert.assertTrue(dsw1.isAlive());
PhysicsInstance dsw2 = manager.getPhysicsInstanceByName("dsw2");
Assert.assertFalse(dsw2.asSelectRead());
Assert.assertFalse(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 {
checkSelect1().accept(heartBeatStrategy);
}
count++;
}
};
manager.putHeartFlow("c0", "dsw1", consumer);
manager.putHeartFlow("c0", "dsw2", 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);
}
Aggregations