Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -86,6 +86,11 @@ | |||||
<artifactId>sentinel-datasource-extension</artifactId> | <artifactId>sentinel-datasource-extension</artifactId> | ||||
<version>${project.version}</version> | <version>${project.version}</version> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>com.alibaba.csp</groupId> | |||||
<artifactId>sentinel-datasource-nacos</artifactId> | |||||
<version>${project.version}</version> | |||||
</dependency> | |||||
<dependency> | <dependency> | ||||
<groupId>com.alibaba.csp</groupId> | <groupId>com.alibaba.csp</groupId> | ||||
<artifactId>sentinel-adapter</artifactId> | <artifactId>sentinel-adapter</artifactId> | ||||
@@ -17,6 +17,7 @@ | |||||
<module>sentinel-demo-dynamic-file-rule</module> | <module>sentinel-demo-dynamic-file-rule</module> | ||||
<module>sentinel-demo-rocketmq</module> | <module>sentinel-demo-rocketmq</module> | ||||
<module>sentinel-demo-dubbo</module> | <module>sentinel-demo-dubbo</module> | ||||
<module>sentinel-demo-nacos-datasource</module> | |||||
</modules> | </modules> | ||||
<dependencies> | <dependencies> | ||||
@@ -24,10 +25,6 @@ | |||||
<groupId>com.alibaba.csp</groupId> | <groupId>com.alibaba.csp</groupId> | ||||
<artifactId>sentinel-core</artifactId> | <artifactId>sentinel-core</artifactId> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>com.alibaba.csp</groupId> | |||||
<artifactId>sentinel-datasource-extension</artifactId> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</project> | </project> |
@@ -19,6 +19,11 @@ | |||||
<groupId>com.alibaba.csp</groupId> | <groupId>com.alibaba.csp</groupId> | ||||
<artifactId>sentinel-datasource-extension</artifactId> | <artifactId>sentinel-datasource-extension</artifactId> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>com.alibaba</groupId> | |||||
<artifactId>fastjson</artifactId> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</project> | </project> |
@@ -0,0 +1,48 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||||
<parent> | |||||
<artifactId>sentinel-demo</artifactId> | |||||
<groupId>com.alibaba.csp</groupId> | |||||
<version>0.1.1-SNAPSHOT</version> | |||||
</parent> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<artifactId>sentinel-demo-nacos-datasource</artifactId> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.alibaba.csp</groupId> | |||||
<artifactId>sentinel-core</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba.csp</groupId> | |||||
<artifactId>sentinel-datasource-extension</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba.csp</groupId> | |||||
<artifactId>sentinel-datasource-nacos</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.alibaba</groupId> | |||||
<artifactId>fastjson</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | |||||
<version>${maven.compiler.version}</version> | |||||
<configuration> | |||||
<source>1.8</source> | |||||
<target>1.8</target> | |||||
<encoding>${java.encoding}</encoding> | |||||
</configuration> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -0,0 +1,139 @@ | |||||
/* | |||||
* 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.datasource.nacos; | |||||
import java.util.Random; | |||||
import java.util.concurrent.TimeUnit; | |||||
import java.util.concurrent.atomic.AtomicInteger; | |||||
import com.alibaba.csp.sentinel.Entry; | |||||
import com.alibaba.csp.sentinel.SphU; | |||||
import com.alibaba.csp.sentinel.slots.block.BlockException; | |||||
import com.alibaba.csp.sentinel.util.TimeUtil; | |||||
/** | |||||
* Flow QPS runner. | |||||
* | |||||
* @author Carpenter Lee | |||||
* @author Eric Zhao | |||||
*/ | |||||
class FlowQpsRunner { | |||||
private final String resourceName; | |||||
private final int threadCount; | |||||
private int seconds; | |||||
public FlowQpsRunner(String resourceName, int threadCount, int seconds) { | |||||
this.resourceName = resourceName; | |||||
this.threadCount = threadCount; | |||||
this.seconds = seconds; | |||||
} | |||||
private final AtomicInteger pass = new AtomicInteger(); | |||||
private final AtomicInteger block = new AtomicInteger(); | |||||
private final AtomicInteger total = new AtomicInteger(); | |||||
private volatile boolean stop = false; | |||||
public void simulateTraffic() { | |||||
for (int i = 0; i < threadCount; i++) { | |||||
Thread t = new Thread(new RunTask()); | |||||
t.setName("simulate-traffic-Task"); | |||||
t.start(); | |||||
} | |||||
} | |||||
public void tick() { | |||||
Thread timer = new Thread(new TimerTask()); | |||||
timer.setName("sentinel-timer-task"); | |||||
timer.start(); | |||||
} | |||||
final class RunTask implements Runnable { | |||||
@Override | |||||
public void run() { | |||||
while (!stop) { | |||||
Entry entry = null; | |||||
try { | |||||
entry = SphU.entry(resourceName); | |||||
// token acquired, means pass | |||||
pass.addAndGet(1); | |||||
} catch (BlockException e1) { | |||||
block.incrementAndGet(); | |||||
} catch (Exception e2) { | |||||
// biz exception | |||||
} finally { | |||||
total.incrementAndGet(); | |||||
if (entry != null) { | |||||
entry.exit(); | |||||
} | |||||
} | |||||
Random random2 = new Random(); | |||||
try { | |||||
TimeUnit.MILLISECONDS.sleep(random2.nextInt(50)); | |||||
} catch (InterruptedException e) { | |||||
// ignore | |||||
} | |||||
} | |||||
} | |||||
} | |||||
final class TimerTask implements Runnable { | |||||
@Override | |||||
public void run() { | |||||
long start = System.currentTimeMillis(); | |||||
System.out.println("begin to statistic!!!"); | |||||
long oldTotal = 0; | |||||
long oldPass = 0; | |||||
long oldBlock = 0; | |||||
while (!stop) { | |||||
try { | |||||
TimeUnit.SECONDS.sleep(1); | |||||
} catch (InterruptedException e) { | |||||
} | |||||
long globalTotal = total.get(); | |||||
long oneSecondTotal = globalTotal - oldTotal; | |||||
oldTotal = globalTotal; | |||||
long globalPass = pass.get(); | |||||
long oneSecondPass = globalPass - oldPass; | |||||
oldPass = globalPass; | |||||
long globalBlock = block.get(); | |||||
long oneSecondBlock = globalBlock - oldBlock; | |||||
oldBlock = globalBlock; | |||||
System.out.println(seconds + " send qps is: " + oneSecondTotal); | |||||
System.out.println(TimeUtil.currentTimeMillis() + ", total:" + oneSecondTotal | |||||
+ ", pass:" + oneSecondPass | |||||
+ ", block:" + oneSecondBlock); | |||||
if (seconds-- <= 0) { | |||||
stop = true; | |||||
} | |||||
} | |||||
long cost = System.currentTimeMillis() - start; | |||||
System.out.println("time cost: " + cost + " ms"); | |||||
System.out.println("total:" + total.get() + ", pass:" + pass.get() | |||||
+ ", block:" + block.get()); | |||||
System.exit(0); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,45 @@ | |||||
/* | |||||
* 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.datasource.nacos; | |||||
import com.alibaba.nacos.api.NacosFactory; | |||||
import com.alibaba.nacos.api.config.ConfigService; | |||||
/** | |||||
* Nacos config sender for demo. | |||||
* | |||||
* @author Eric Zhao | |||||
*/ | |||||
public class NacosConfigSender { | |||||
public static void main(String[] args) throws Exception { | |||||
final String remoteAddress = "localhost"; | |||||
final String groupId = "Sentinel:Demo"; | |||||
final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule"; | |||||
final String rule = "[\n" | |||||
+ " {\n" | |||||
+ " \"resource\": \"TestResource\",\n" | |||||
+ " \"controlBehavior\": 0,\n" | |||||
+ " \"count\": 5.0,\n" | |||||
+ " \"grade\": 1,\n" | |||||
+ " \"limitApp\": \"default\",\n" | |||||
+ " \"strategy\": 0\n" | |||||
+ " }\n" | |||||
+ "]"; | |||||
ConfigService configService = NacosFactory.createConfigService(remoteAddress); | |||||
System.out.println(configService.publishConfig(dataId, groupId, rule)); | |||||
} | |||||
} |
@@ -0,0 +1,56 @@ | |||||
/* | |||||
* 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.datasource.nacos; | |||||
import java.util.List; | |||||
import com.alibaba.csp.sentinel.datasource.DataSource; | |||||
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource; | |||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; | |||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
/** | |||||
* This demo demonstrates how to use Nacos as the data source of Sentinel rules. | |||||
* | |||||
* Before you start, you need to start a Nacos server in local first, and then | |||||
* use {@link NacosConfigSender} to publish initial rule configuration to Nacos. | |||||
* | |||||
* @author Eric Zhao | |||||
*/ | |||||
public class NacosDataSourceDemo { | |||||
private static final String KEY = "TestResource"; | |||||
public static void main(String[] args) { | |||||
loadRules(); | |||||
// Assume we config: resource is `TestResource`, initial QPS threshold is 5. | |||||
FlowQpsRunner runner = new FlowQpsRunner(KEY, 1, 100); | |||||
runner.simulateTraffic(); | |||||
runner.tick(); | |||||
} | |||||
private static void loadRules() { | |||||
final String remoteAddress = "localhost"; | |||||
final String groupId = "Sentinel:Demo"; | |||||
final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule"; | |||||
DataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, | |||||
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})); | |||||
FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); | |||||
} | |||||
} |