From f01fe2b437191fb405a3c159c068abd9822c12ae Mon Sep 17 00:00:00 2001 From: Eric Zhao Date: Sun, 9 Dec 2018 21:56:22 +0800 Subject: [PATCH] Add demo module for Sentinel cluster flow control Signed-off-by: Eric Zhao --- sentinel-demo/pom.xml | 1 + sentinel-demo/sentinel-demo-cluster/pom.xml | 44 ++++++++++++ .../demo/cluster/ClusterClientDemo.java | 61 ++++++++++++++++ .../demo/cluster/ClusterServerDemo.java | 50 +++++++++++++ .../sentinel/demo/cluster/DemoConstants.java | 29 ++++++++ .../init/DemoClusterClientInitFunc.java | 57 +++++++++++++++ .../init/DemoClusterServerInitFunc.java | 71 +++++++++++++++++++ .../com.alibaba.csp.sentinel.init.InitFunc | 2 + 8 files changed, 315 insertions(+) create mode 100644 sentinel-demo/sentinel-demo-cluster/pom.xml create mode 100644 sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java create mode 100644 sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterServerDemo.java create mode 100644 sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/DemoConstants.java create mode 100644 sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterClientInitFunc.java create mode 100644 sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterServerInitFunc.java create mode 100755 sentinel-demo/sentinel-demo-cluster/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.init.InitFunc diff --git a/sentinel-demo/pom.xml b/sentinel-demo/pom.xml index 3ab45f6f..2cc6f9ad 100755 --- a/sentinel-demo/pom.xml +++ b/sentinel-demo/pom.xml @@ -28,6 +28,7 @@ sentinel-demo-annotation-spring-aop sentinel-demo-parameter-flow-control sentinel-demo-slot-chain-spi + sentinel-demo-cluster diff --git a/sentinel-demo/sentinel-demo-cluster/pom.xml b/sentinel-demo/sentinel-demo-cluster/pom.xml new file mode 100644 index 00000000..e76d8bb5 --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/pom.xml @@ -0,0 +1,44 @@ + + + + sentinel-demo + com.alibaba.csp + 1.4.0-SNAPSHOT + + 4.0.0 + + sentinel-demo-cluster + + + + com.alibaba.csp + sentinel-core + + + com.alibaba.csp + sentinel-transport-simple-http + + + com.alibaba.csp + sentinel-parameter-flow-control + + + + com.alibaba.csp + sentinel-cluster-client-default + ${project.version} + + + com.alibaba.csp + sentinel-cluster-server-default + ${project.version} + + + + com.alibaba.csp + sentinel-datasource-nacos + + + \ No newline at end of file diff --git a/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java new file mode 100644 index 00000000..c665fc3a --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterClientDemo.java @@ -0,0 +1,61 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel.demo.cluster; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.EntryType; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.cluster.ClusterStateManager; +import com.alibaba.csp.sentinel.init.InitExecutor; +import com.alibaba.csp.sentinel.slots.block.BlockException; + +/** + *

Run this demo with the following args: -Dproject.name=appA

+ * + * @author Eric Zhao + */ +public class ClusterClientDemo { + + public static void main(String[] args) { + InitExecutor.doInit(); + + // Manually schedule the cluster mode to client. + // In common, we need a scheduling system to modify the cluster mode automatically. + // Command HTTP API: http://:/setClusterMode?mode= + ClusterStateManager.setToClient(); + + String resourceName = "cluster-demo-entry"; + + // Assume we have a cluster flow rule for `demo-resource`: QPS = 5 in AVG_LOCAL mode. + for (int i = 0; i < 10; i++) { + tryEntry(resourceName); + } + } + + private static void tryEntry(String res) { + Entry entry = null; + try { + entry = SphU.entry(res, EntryType.IN, 1, "abc", "def"); + System.out.println("Passed"); + } catch (BlockException ex) { + ex.printStackTrace(); + } finally { + if (entry != null) { + entry.exit(); + } + } + } +} diff --git a/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterServerDemo.java b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterServerDemo.java new file mode 100644 index 00000000..8d731f28 --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/ClusterServerDemo.java @@ -0,0 +1,50 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel.demo.cluster; + +import java.util.Collections; + +import com.alibaba.csp.sentinel.cluster.server.ClusterTokenServer; +import com.alibaba.csp.sentinel.cluster.server.SentinelDefaultTokenServer; +import com.alibaba.csp.sentinel.cluster.server.config.ClusterServerConfigManager; +import com.alibaba.csp.sentinel.cluster.server.config.ServerTransportConfig; + +/** + * Cluster server demo (alone mode). + * + * Here we init the cluster server dynamic data sources in {@link com.alibaba.csp.sentinel.demo.cluster.init.DemoClusterServerInitFunc}. + * + * @author Eric Zhao + * @since 1.4.0 + */ +public class ClusterServerDemo { + + public static void main(String[] args) throws Exception { + // Not embedded mode by default (alone mode). + ClusterTokenServer tokenServer = new SentinelDefaultTokenServer(); + + // A sample for manually load config for cluster server. + // It's recommended to use dynamic data source to cluster manage config and rules. + // See the sample in DemoClusterServerInitFunc for detail. + ClusterServerConfigManager.loadGlobalTransportConfig(new ServerTransportConfig() + .setIdleSeconds(600) + .setPort(11111)); + ClusterServerConfigManager.loadServerNamespaceSet(Collections.singleton(DemoConstants.APP_NAME)); + + // Start the server. + tokenServer.start(); + } +} diff --git a/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/DemoConstants.java b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/DemoConstants.java new file mode 100644 index 00000000..06ee4e03 --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/DemoConstants.java @@ -0,0 +1,29 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel.demo.cluster; + +/** + * @author Eric Zhao + */ +public final class DemoConstants { + + public static final String APP_NAME = "appA"; + + public static final String FLOW_POSTFIX = "-flow-rules"; + public static final String PARAM_FLOW_POSTFIX = "-param-rules"; + + private DemoConstants() {} +} diff --git a/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterClientInitFunc.java b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterClientInitFunc.java new file mode 100644 index 00000000..d75804be --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterClientInitFunc.java @@ -0,0 +1,57 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel.demo.cluster.init; + +import java.util.List; + +import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfig; +import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfigManager; +import com.alibaba.csp.sentinel.datasource.ReadableDataSource; +import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource; +import com.alibaba.csp.sentinel.demo.cluster.DemoConstants; +import com.alibaba.csp.sentinel.init.InitFunc; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; +import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +/** + * @author Eric Zhao + */ +public class DemoClusterClientInitFunc implements InitFunc { + + @Override + public void init() throws Exception { + final String remoteAddress = "localhost"; + final String groupId = "SENTINEL_GROUP"; + final String flowDataId = DemoConstants.APP_NAME + DemoConstants.FLOW_POSTFIX; + final String paramDataId = DemoConstants.APP_NAME + DemoConstants.PARAM_FLOW_POSTFIX; + final String configDataId = DemoConstants.APP_NAME + "-cluster-client-config"; + + ReadableDataSource> ruleSource = new NacosDataSource<>(remoteAddress, groupId, + flowDataId, source -> JSON.parseObject(source, new TypeReference>() {})); + FlowRuleManager.register2Property(ruleSource.getProperty()); + ReadableDataSource> paramRuleSource = new NacosDataSource<>(remoteAddress, groupId, + paramDataId, source -> JSON.parseObject(source, new TypeReference>() {})); + ParamFlowRuleManager.register2Property(paramRuleSource.getProperty()); + + ReadableDataSource dataSource = new NacosDataSource<>(remoteAddress, groupId, + configDataId, source -> JSON.parseObject(source, new TypeReference() {})); + ClusterClientConfigManager.register2Property(dataSource.getProperty()); + } +} diff --git a/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterServerInitFunc.java b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterServerInitFunc.java new file mode 100644 index 00000000..8fe5313a --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/src/main/java/com/alibaba/csp/sentinel/demo/cluster/init/DemoClusterServerInitFunc.java @@ -0,0 +1,71 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel.demo.cluster.init; + +import java.util.List; +import java.util.Set; + +import com.alibaba.csp.sentinel.cluster.flow.rule.ClusterFlowRuleManager; +import com.alibaba.csp.sentinel.cluster.flow.rule.ClusterParamFlowRuleManager; +import com.alibaba.csp.sentinel.cluster.server.config.ClusterServerConfigManager; +import com.alibaba.csp.sentinel.cluster.server.config.ServerTransportConfig; +import com.alibaba.csp.sentinel.datasource.ReadableDataSource; +import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource; +import com.alibaba.csp.sentinel.demo.cluster.DemoConstants; +import com.alibaba.csp.sentinel.init.InitFunc; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +/** + * @author Eric Zhao + */ +public class DemoClusterServerInitFunc implements InitFunc { + + private final String remoteAddress = "localhost"; + private final String groupId = "SENTINEL_GROUP"; + private final String namespaceSetDataId = "cluster-server-namespace-set"; + private final String serverTransportDataId = "cluster-server-transport-config"; + + @Override + public void init() throws Exception { + // Register cluster flow rule property supplier which creates data source by namespace. + ClusterFlowRuleManager.setPropertySupplier(namespace -> { + ReadableDataSource> ds = new NacosDataSource<>(remoteAddress, groupId, + namespace + DemoConstants.FLOW_POSTFIX, + source -> JSON.parseObject(source, new TypeReference>() {})); + return ds.getProperty(); + }); + // Register cluster parameter flow rule property supplier. + ClusterParamFlowRuleManager.setPropertySupplier(namespace -> { + ReadableDataSource> ds = new NacosDataSource<>(remoteAddress, groupId, + namespace + DemoConstants.PARAM_FLOW_POSTFIX, + source -> JSON.parseObject(source, new TypeReference>() {})); + return ds.getProperty(); + }); + + // Server namespace set (scope) data source. + ReadableDataSource> namespaceDs = new NacosDataSource<>(remoteAddress, groupId, + namespaceSetDataId, source -> JSON.parseObject(source, new TypeReference>() {})); + ClusterServerConfigManager.registerNamespaceSetProperty(namespaceDs.getProperty()); + // Server transport configuration data source. + ReadableDataSource transportConfigDs = new NacosDataSource<>(remoteAddress, + groupId, serverTransportDataId, + source -> JSON.parseObject(source, new TypeReference() {})); + ClusterServerConfigManager.registerServerTransportProperty(transportConfigDs.getProperty()); + } +} diff --git a/sentinel-demo/sentinel-demo-cluster/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.init.InitFunc b/sentinel-demo/sentinel-demo-cluster/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.init.InitFunc new file mode 100755 index 00000000..11b70ec5 --- /dev/null +++ b/sentinel-demo/sentinel-demo-cluster/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.init.InitFunc @@ -0,0 +1,2 @@ +com.alibaba.csp.sentinel.demo.cluster.init.DemoClusterClientInitFunc +com.alibaba.csp.sentinel.demo.cluster.init.DemoClusterServerInitFunc \ No newline at end of file