@@ -86,6 +86,11 @@ | |||
<artifactId>sentinel-datasource-extension</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba.csp</groupId> | |||
<artifactId>sentinel-datasource-nacos</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba.csp</groupId> | |||
<artifactId>sentinel-adapter</artifactId> | |||
@@ -17,6 +17,7 @@ | |||
<module>sentinel-demo-dynamic-file-rule</module> | |||
<module>sentinel-demo-rocketmq</module> | |||
<module>sentinel-demo-dubbo</module> | |||
<module>sentinel-demo-nacos-datasource</module> | |||
</modules> | |||
<dependencies> | |||
@@ -24,10 +25,6 @@ | |||
<groupId>com.alibaba.csp</groupId> | |||
<artifactId>sentinel-core</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba.csp</groupId> | |||
<artifactId>sentinel-datasource-extension</artifactId> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -19,6 +19,11 @@ | |||
<groupId>com.alibaba.csp</groupId> | |||
<artifactId>sentinel-datasource-extension</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba</groupId> | |||
<artifactId>fastjson</artifactId> | |||
</dependency> | |||
</dependencies> | |||
</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()); | |||
} | |||
} |