Search in sources :

Example 1 with ClusterConfig

use of io.mycat.config.ClusterConfig in project Mycat2 by MyCATApache.

the class TreeItemCellFactory method call.

@Override
public TreeCell<ObjectItem> call(TreeView<ObjectItem> tree) {
    TreeCell<ObjectItem> cell = new SchemaObjectCell();
    cell.setOnMouseClicked(event -> {
        Optional<Command> commandOptional = Command.parsePath(getPath(cell.getTreeItem()));
        if (event != null) {
            if (event.getButton() == MouseButton.SECONDARY) {
                ContextMenu contextMenu = new ContextMenu();
                TreeItem<ObjectItem> treeItem = cell.getTreeItem();
                if (treeItem == null) {
                    return;
                }
                if (!treeItem.isLeaf() && treeItem.getParent() == tree.getRoot()) {
                    ObjectItem value = treeItem.getValue();
                    switch(value.getText()) {
                        case "schemas":
                            {
                                MenuItem item1 = new MenuItem("新建逻辑库");
                                item1.setId("addSchema");
                                item1.setOnAction(new EventHandler<ActionEvent>() {

                                    @Override
                                    public void handle(ActionEvent event1) {
                                        try {
                                            controller.edit(new LogicSchemaConfig());
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    }
                                });
                                contextMenu.getItems().add(item1);
                                break;
                            }
                        case "datasources":
                            {
                                MenuItem item1 = new MenuItem("新建数据源");
                                item1.setId("addDatasource");
                                item1.setOnAction(new EventHandler<ActionEvent>() {

                                    @Override
                                    public void handle(ActionEvent event1) {
                                        try {
                                            controller.edit(new DatasourceConfig());
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    }
                                });
                                contextMenu.getItems().add(item1);
                                break;
                            }
                        case "clusters":
                            {
                                MenuItem item1 = new MenuItem("新建集群");
                                item1.setId("addCluster");
                                item1.setOnAction(new EventHandler<ActionEvent>() {

                                    @Override
                                    public void handle(ActionEvent event1) {
                                        try {
                                            controller.edit(new ClusterConfig());
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    }
                                });
                                contextMenu.getItems().add(item1);
                                break;
                            }
                    }
                } else {
                    if (commandOptional.isPresent()) {
                        Command command = commandOptional.get();
                        String schema = command.getSchema();
                        switch(command.getType()) {
                            case SCHEMA:
                                {
                                    MenuItem item1 = new MenuItem("删除逻辑库配置");
                                    item1.setId("deleteSchema");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除逻辑库配置", "确认删除逻辑库配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteLogicalSchema(command.getSchema());
                                                    controller.flashRoot();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SHARDING_TABLES:
                                {
                                    MenuItem item1 = new MenuItem("新建分片表");
                                    item1.setId("addShardingTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                controller.addShardingTable(schema);
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case GLOBAL_TABLES:
                                {
                                    MenuItem item1 = new MenuItem("新建全局表");
                                    item1.setId("addGlobalTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                controller.addGlobalTableConfig(schema);
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SINGLE_TABLES:
                                {
                                    MenuItem item1 = new MenuItem("新建单表");
                                    item1.setId("addSingleTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                controller.addNormalTableConfig(schema);
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SHARDING_TABLE:
                                {
                                    MenuItem item1 = new MenuItem("删除分片表配置");
                                    item1.setId("deleteShardingTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除分片表", "确认删除分片表配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteTable(schema, command.getTable());
                                                    controller.flashSchemas();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case GLOBAL_TABLE:
                                {
                                    MenuItem item1 = new MenuItem("删除全局表配置");
                                    item1.setId("deleteGlobalTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除全局表配置", "确认删除全局表配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteTable(command.getSchema(), command.getTable());
                                                    controller.flashSchemas();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case SINGLE_TABLE:
                                {
                                    MenuItem item1 = new MenuItem("删除单表配置");
                                    item1.setId("deleteSingleTable");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除单表配置", "确认删除单表配置");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteTable(command.getSchema(), command.getTable());
                                                    controller.flashSchemas();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case CLUSTER:
                                {
                                    MenuItem item1 = new MenuItem("删除");
                                    item1.setId("deleteCluster");
                                    item1.setOnAction(new EventHandler<ActionEvent>() {

                                        @Override
                                        public void handle(ActionEvent event1) {
                                            try {
                                                boolean doAction = display("删除集群", "确认删除集群");
                                                if (doAction) {
                                                    controller.getInfoProvider().deleteCluster(command.getCluster());
                                                    controller.flashClusterAndDataSource();
                                                }
                                            } catch (Exception e) {
                                                popAlter(e);
                                            }
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                            case DATASOURCE:
                                {
                                    MenuItem item1 = new MenuItem("删除");
                                    item1.setId("deleteDatasource");
                                    item1.setOnAction(event1 -> {
                                        try {
                                            boolean doAction = display("删除数据源", "确认删除数据源");
                                            if (doAction) {
                                                controller.getInfoProvider().deleteDatasource(command.getDatasource());
                                                controller.flashClusterAndDataSource();
                                            }
                                        } catch (Exception e) {
                                            popAlter(e);
                                        }
                                    });
                                    contextMenu.getItems().add(item1);
                                    break;
                                }
                        }
                    }
                }
                if (contextMenu != null) {
                    cell.setContextMenu(contextMenu);
                }
            }
        }
        if (!cell.isEmpty()) {
            controller.clearObjectInfo();
            if (!commandOptional.isPresent()) {
                return;
            }
            Command command = commandOptional.get();
            switch(command.getType()) {
                case SCHEMA:
                    Optional<LogicSchemaConfig> logicSchemaConfigOptional = controller.getInfoProvider().getSchemaConfigByName(command.getSchema());
                    logicSchemaConfigOptional.ifPresent(r -> controller.edit(r));
                    break;
                case SHARDING_TABLE:
                case GLOBAL_TABLE:
                case SINGLE_TABLE:
                    {
                        if (command.getSchema() == null || command.getTable() == null) {
                            return;
                        }
                        LogicTableType logicTableType;
                        String schemaName = command.getSchema();
                        String tableName = command.getTable();
                        switch(command.getType()) {
                            case GLOBAL_TABLE:
                                logicTableType = LogicTableType.GLOBAL;
                                break;
                            case SINGLE_TABLE:
                                logicTableType = LogicTableType.NORMAL;
                                break;
                            case SHARDING_TABLE:
                                logicTableType = LogicTableType.SHARDING;
                                break;
                            default:
                                throw new IllegalArgumentException();
                        }
                        Optional<Object> config = controller.getInfoProvider().getTableConfigByName(command.getSchema(), command.getTable());
                        config.ifPresent(c -> controller.edit(logicTableType, schemaName, tableName, c));
                        break;
                    }
                case CLUSTER:
                    Optional<ClusterConfig> clusterConfigOptional = controller.getInfoProvider().getClusterConfigByPath(command.getCluster());
                    clusterConfigOptional.ifPresent(c -> controller.edit(c));
                    break;
                case DATASOURCE:
                    Optional<DatasourceConfig> datasourceConfigOptional = controller.getInfoProvider().getDatasourceConfigByPath(command.getDatasource());
                    datasourceConfigOptional.ifPresent(c -> controller.edit(c));
                    break;
            }
            System.out.println("");
        }
    });
    return cell;
}
Also used : ClusterConfig(io.mycat.config.ClusterConfig) EventHandler(javafx.event.EventHandler) Pos(javafx.geometry.Pos) Scene(javafx.scene.Scene) HBox(javafx.scene.layout.HBox) MouseButton(javafx.scene.input.MouseButton) Modality(javafx.stage.Modality) javafx.scene.control(javafx.scene.control) MainPaneVO.popAlter(io.mycat.ui.MainPaneVO.popAlter) Node(javafx.scene.Node) UIMain.getPath(io.mycat.ui.UIMain.getPath) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VBox(javafx.scene.layout.VBox) ActionEvent(javafx.event.ActionEvent) Stage(javafx.stage.Stage) LogicTableType(io.mycat.LogicTableType) LogicSchemaConfig(io.mycat.config.LogicSchemaConfig) Optional(java.util.Optional) DatasourceConfig(io.mycat.config.DatasourceConfig) Callback(javafx.util.Callback) Optional(java.util.Optional) ActionEvent(javafx.event.ActionEvent) EventHandler(javafx.event.EventHandler) LogicTableType(io.mycat.LogicTableType) DatasourceConfig(io.mycat.config.DatasourceConfig) LogicSchemaConfig(io.mycat.config.LogicSchemaConfig) ClusterConfig(io.mycat.config.ClusterConfig)

Example 2 with ClusterConfig

use of io.mycat.config.ClusterConfig in project Mycat2 by MyCATApache.

the class MGRTest method testSlaveBroken.

@Test
public void testSlaveBroken() {
    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();
    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());
        }
    }));
    manager.putHeartFlow("c0", "dsw1", checkMGR(true));
    manager.putHeartFlow("c0", "dsw2", checkMGR(false));
    manager.putHeartFlow("c0", "dsr1", makeBroken());
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    // 测试已经切换
    Set<String> balanceTargets = new HashSet<>();
    test(() -> {
        balanceTargets.add(manager.getDatasourceNameByReplicaName("c0", false, null));
        return false;
    });
    Assert.assertFalse(balanceTargets.contains("dsr1"));
    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", "dsr1", checkMGR(false));
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    PhysicsInstance dsr1 = manager.getPhysicsInstanceByName("dsr1");
    Assert.assertTrue(dsr1.asSelectRead());
    Assert.assertTrue(dsr1.isAlive());
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) DatasourceConfig(io.mycat.config.DatasourceConfig) ConfigReporter(io.mycat.ConfigReporter) ClusterConfig(io.mycat.config.ClusterConfig) Test(org.junit.Test)

Example 3 with ClusterConfig

use of io.mycat.config.ClusterConfig 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);
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) CreateDataSourceHint(io.mycat.hint.CreateDataSourceHint) CreateClusterHint(io.mycat.hint.CreateClusterHint) MGRHeartBeatStrategy(io.mycat.replica.heartbeat.strategy.MGRHeartBeatStrategy) 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)

Example 4 with ClusterConfig

use of io.mycat.config.ClusterConfig in project Mycat2 by MyCATApache.

the class MGRTest method test.

@Test
public void test() {
    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.putHeartFlow("c0", "dsw1", checkMGR(true));
    manager.putHeartFlow("c0", "dsw2", checkMGR(false));
    manager.putHeartFlow("c0", "dsr1", checkMGR(false));
    manager.start();
    for (Runnable runnable : runnables) {
        runnable.run();
    }
    for (PhysicsInstance physicsInstance : manager.getPhysicsInstances()) {
        Assert.assertTrue(physicsInstance.asSelectRead());
    }
    Set<String> balanceTargets = new HashSet<>();
    test(() -> {
        balanceTargets.add(manager.getDatasourceNameByReplicaName("c0", false, null));
        return balanceTargets.size() == 3;
    });
    Assert.assertEquals(3, balanceTargets.size());
    Set<String> masterTargets = new HashSet<>();
    test(() -> {
        masterTargets.add(manager.getDatasourceNameByReplicaName("c0", true, null));
        return false;
    });
    Assert.assertEquals(1, masterTargets.size());
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) DatasourceConfig(io.mycat.config.DatasourceConfig) ClusterConfig(io.mycat.config.ClusterConfig) Test(org.junit.Test)

Example 5 with ClusterConfig

use of io.mycat.config.ClusterConfig 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);
}
Also used : TimerConfig(io.mycat.config.TimerConfig) LoadBalanceManager(io.mycat.plug.loadBalance.LoadBalanceManager) CreateDataSourceHint(io.mycat.hint.CreateDataSourceHint) CreateClusterHint(io.mycat.hint.CreateClusterHint) 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

ClusterConfig (io.mycat.config.ClusterConfig)31 DatasourceConfig (io.mycat.config.DatasourceConfig)26 LoadBalanceManager (io.mycat.plug.loadBalance.LoadBalanceManager)24 TimerConfig (io.mycat.config.TimerConfig)22 Test (org.junit.Test)22 ConfigReporter (io.mycat.ConfigReporter)16 Consumer (java.util.function.Consumer)7 CreateClusterHint (io.mycat.hint.CreateClusterHint)6 CreateDataSourceHint (io.mycat.hint.CreateDataSourceHint)6 HeartBeatStrategy (io.mycat.replica.heartbeat.HeartBeatStrategy)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 ReplicaSelectorManager (io.mycat.replica.ReplicaSelectorManager)3 SchemaHandler (io.mycat.calcite.table.SchemaHandler)2 ServerConfig (io.mycat.config.ServerConfig)2 DruidDatasourceProvider (io.mycat.datasource.jdbc.DruidDatasourceProvider)2 JdbcConnectionManager (io.mycat.datasource.jdbc.datasource.JdbcConnectionManager)2 NameMap (io.mycat.util.NameMap)2 java.util (java.util)2 Collectors (java.util.stream.Collectors)2 Logger (org.slf4j.Logger)2