@@ -22,7 +22,8 @@ | |||
<module>sentinel-demo-apollo-datasource</module> | |||
<module>sentinel-demo-annotation-spring-aop</module> | |||
<module>sentinel-demo-parameter-flow-control</module> | |||
<module>sentinel-demo-slot-chain-spi</module> | |||
<module>sentinel-demo-slot-spi</module> | |||
<module>sentinel-demo-slotchain-spi</module> | |||
<module>sentinel-demo-cluster</module> | |||
<module>sentinel-demo-command-handler</module> | |||
<module>sentinel-demo-spring-webflux</module> | |||
@@ -1,30 +0,0 @@ | |||
/* | |||
* 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.slot; | |||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain; | |||
import com.alibaba.csp.sentinel.slotchain.SlotChainBuilder; | |||
import com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder; | |||
/** | |||
* @author Eric Zhao | |||
* | |||
* @deprecated since 1.7.2, we can use @SpiOrder(-3500) to adjust the order of {@link DemoSlot}, | |||
* this class is reserved for compatibility with older versions. | |||
*/ | |||
@Deprecated | |||
public class DemoSlotChainBuilder extends DefaultSlotChainBuilder { | |||
} |
@@ -1,2 +0,0 @@ | |||
# Custom slot processor | |||
com.alibaba.csp.sentinel.demo.slot.DemoSlot |
@@ -9,6 +9,5 @@ | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>sentinel-demo-slot-chain-spi</artifactId> | |||
<artifactId>sentinel-demo-slot-spi</artifactId> | |||
</project> |
@@ -20,13 +20,15 @@ import com.alibaba.csp.sentinel.SphU; | |||
import com.alibaba.csp.sentinel.slots.block.BlockException; | |||
/** | |||
* Demo for adding custom slot. | |||
* @see {@link DemoSlot}. | |||
* | |||
* @author Eric Zhao | |||
* @author cdfive | |||
*/ | |||
public class SlotChainBuilderSpiDemo { | |||
public class DemoApplication { | |||
public static void main(String[] args) { | |||
// You will see this in record.log, indicating that the custom slot chain builder is activated: | |||
// [SlotChainProvider] Global slot chain builder resolved: com.alibaba.csp.sentinel.demo.slot.DemoSlotChainBuilder | |||
Entry entry = null; | |||
try { | |||
entry = SphU.entry("abc"); |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 1999-2018 Alibaba Group Holding Ltd. | |||
* Copyright 1999-2021 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. | |||
@@ -15,23 +15,32 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.demo.slot; | |||
import com.alibaba.csp.sentinel.Constants; | |||
import com.alibaba.csp.sentinel.context.Context; | |||
import com.alibaba.csp.sentinel.node.DefaultNode; | |||
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot; | |||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot; | |||
import com.alibaba.csp.sentinel.slots.block.flow.FlowSlot; | |||
import com.alibaba.csp.sentinel.spi.Spi; | |||
/** | |||
* An example slot that records current context and entry resource. | |||
* A demo slot that records current context and entry resource. | |||
* | |||
* Note that the value of order attribute in `@Spi` is -1500, the smaller the value, the higher the order, | |||
* so this slot will be executed after {@link FlowSlot}(order=-2000) and before {@link DegradeSlot}(order=-1000), | |||
* refer to the constants for slot order definitions in {@link Constants}. | |||
* | |||
* @author Eric Zhao | |||
* @author cdfive | |||
*/ | |||
@Spi(order = -3500) | |||
@Spi(order = -1500) | |||
public class DemoSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
@Override | |||
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args) | |||
throws Throwable { | |||
System.out.println("------Entering for entry on DemoSlot------"); | |||
System.out.println("Current context: " + context.getName()); | |||
System.out.println("Current entry resource: " + context.getCurEntry().getResourceWrapper().getName()); | |||
@@ -40,7 +49,9 @@ public class DemoSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
@Override | |||
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) { | |||
System.out.println("Exiting for entry on DemoSlot: " + context.getCurEntry().getResourceWrapper().getName()); | |||
System.out.println("------Exiting for entry on DemoSlot------"); | |||
System.out.println("Current context: " + context.getName()); | |||
System.out.println("Current entry resource: " + context.getCurEntry().getResourceWrapper().getName()); | |||
fireExit(context, resourceWrapper, count, args); | |||
} |
@@ -0,0 +1,2 @@ | |||
# Custom ProcessorSlot | |||
com.alibaba.csp.sentinel.demo.slot.DemoSlot |
@@ -0,0 +1,13 @@ | |||
<?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>1.8.2-SNAPSHOT</version> | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>sentinel-demo-slotchain-spi</artifactId> | |||
</project> |
@@ -0,0 +1,78 @@ | |||
/* | |||
* Copyright 1999-2021 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.slotchain; | |||
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.slots.block.degrade.DegradeRule; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.concurrent.ThreadLocalRandom; | |||
import java.util.concurrent.TimeUnit; | |||
/** | |||
* Demo for degrade rule using custom SlotChainBuilder {@link DemoSlotChainBuilder}. | |||
* | |||
* You will see this in sentinel-record.log, indicating that the custom slot chain builder is activated: | |||
* [SlotChainProvider] Global slot chain builder resolved: com.alibaba.csp.sentinel.demo.slotchain.DemoSlotChainBuilder | |||
* | |||
* @author cdfive | |||
*/ | |||
public class DemoDegradeRuleApplication { | |||
private static final String RESOURCE_KEY = "abc"; | |||
public static void main(String[] args) throws Exception { | |||
initDegradeRule(); | |||
for (int i = 1; i <= 100; i++) { | |||
Entry entry = null; | |||
try { | |||
entry = SphU.entry(RESOURCE_KEY); | |||
TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(10, 100)); | |||
System.out.println(i + "=>" + " passed"); | |||
} catch (BlockException ex) { | |||
System.out.println(i + "=>" + " blocked by " + ex.getClass().getSimpleName()); | |||
} finally { | |||
if (entry != null) { | |||
entry.exit(); | |||
} | |||
} | |||
} | |||
} | |||
private static void initDegradeRule() { | |||
List<DegradeRule> rules = new ArrayList<>(); | |||
DegradeRule rule = new DegradeRule(RESOURCE_KEY) | |||
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType()) | |||
// Max allowed response time | |||
.setCount(20) | |||
// Retry timeout (in second) | |||
.setTimeWindow(10) | |||
// Circuit breaker opens when slow request ratio > 20% | |||
.setSlowRatioThreshold(0.2) | |||
.setMinRequestAmount(10) | |||
.setStatIntervalMs(20000); | |||
rules.add(rule); | |||
DegradeRuleManager.loadRules(rules); | |||
System.out.println("Degrade rule loaded: " + rules); | |||
} | |||
} |
@@ -0,0 +1,76 @@ | |||
/* | |||
* Copyright 1999-2021 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.slotchain; | |||
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.slots.block.RuleConstant; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy; | |||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; | |||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.concurrent.ThreadLocalRandom; | |||
import java.util.concurrent.TimeUnit; | |||
/** | |||
* Demo for flow rule using custom SlotChainBuilder {@link DemoSlotChainBuilder}. | |||
* | |||
* You will see this in sentinel-record.log, indicating that the custom slot chain builder is activated: | |||
* [SlotChainProvider] Global slot chain builder resolved: com.alibaba.csp.sentinel.demo.slotchain.DemoSlotChainBuilder | |||
* | |||
* @author cdfive | |||
*/ | |||
public class DemoFlowRuleApplication { | |||
private static final String RESOURCE_KEY = "abc"; | |||
public static void main(String[] args) throws Exception { | |||
initFlowQpsRule(); | |||
for (int i = 1; i <= 100; i++) { | |||
Entry entry = null; | |||
try { | |||
entry = SphU.entry(RESOURCE_KEY); | |||
TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(10, 100)); | |||
System.out.println(i + "=>" + " passed"); | |||
} catch (BlockException ex) { | |||
System.out.println(i + "=>" + " blocked by " + ex.getClass().getSimpleName()); | |||
} finally { | |||
if (entry != null) { | |||
entry.exit(); | |||
} | |||
} | |||
} | |||
} | |||
private static void initFlowQpsRule() { | |||
List<FlowRule> rules = new ArrayList<FlowRule>(); | |||
FlowRule rule1 = new FlowRule(); | |||
rule1.setResource(RESOURCE_KEY); | |||
// set limit qps to 5 | |||
rule1.setCount(5); | |||
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); | |||
rule1.setLimitApp("default"); | |||
rules.add(rule1); | |||
FlowRuleManager.loadRules(rules); | |||
System.out.println("Flow rule loaded: " + rules); | |||
} | |||
} |
@@ -0,0 +1,99 @@ | |||
/* | |||
* Copyright 1999-2021 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.slotchain; | |||
import com.alibaba.csp.sentinel.Constants; | |||
import com.alibaba.csp.sentinel.log.RecordLog; | |||
import com.alibaba.csp.sentinel.slotchain.*; | |||
import com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder; | |||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot; | |||
import com.alibaba.csp.sentinel.spi.Spi; | |||
import com.alibaba.csp.sentinel.spi.SpiLoader; | |||
import java.util.List; | |||
/** | |||
* A demo {@link SlotChainBuilder} for build custom slot chain. | |||
* Two ways to build slot chain are demonstrated. | |||
* | |||
* Pay attention to that `ProcessorSlotChain` is not a SPI, but the `SlotChainBuilder`. | |||
* | |||
* Most of the time, we don't need to customize `SlotChainBuilder`, | |||
* maybe customize `ProcessorSlot` is enough, refer to `sentinel-demo-slot-spi` module. | |||
* | |||
* Note that the sentinel's default slots and the order of them are very important, be careful when customizing, | |||
* refer to the constants for slot order definitions in {@link Constants}. | |||
* You may also refer to {@link DefaultSlotChainBuilder}. | |||
* | |||
* @author cdfive | |||
*/ | |||
@Spi | |||
public class DemoSlotChainBuilder implements SlotChainBuilder { | |||
@Override | |||
public ProcessorSlotChain build() { | |||
ProcessorSlotChain chain = new DefaultProcessorSlotChain(); | |||
List<ProcessorSlot> sortedSlotList = SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted(); | |||
// Filter out `DegradeSlot` | |||
// Test for `DemoDegradeRuleApplication`, the demo will not be blocked by `DegradeException` | |||
sortedSlotList.removeIf(o -> DegradeSlot.class.equals(o.getClass())); | |||
for (ProcessorSlot slot : sortedSlotList) { | |||
if (!(slot instanceof AbstractLinkedProcessorSlot)) { | |||
RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain"); | |||
continue; | |||
} | |||
chain.addLast((AbstractLinkedProcessorSlot<?>) slot); | |||
} | |||
return chain; | |||
} | |||
/** | |||
* Another way to build the slot chain, add slot one by one with `SpiLoader#loadInstance`. | |||
* Note that the sentinel's default slots and the order of them are very important, be careful when customizing, | |||
* refer to the constants for slot order definitions in {@link com.alibaba.csp.sentinel.Constants}. | |||
*/ | |||
/* | |||
@Override | |||
public ProcessorSlotChain build() { | |||
ProcessorSlotChain chain = new DefaultProcessorSlotChain(); | |||
// Create a `SpiLoader` instance | |||
SpiLoader<ProcessorSlot> spiLoader = SpiLoader.of(ProcessorSlot.class); | |||
// Add `NodeSelectorSlot`, load by class | |||
chain.addLast((AbstractLinkedProcessorSlot<?>) spiLoader.loadInstance(NodeSelectorSlot.class)); | |||
// Add `ClusterBuilderSlot`, load by aliasname(default is classname) | |||
chain.addLast((AbstractLinkedProcessorSlot<?>) spiLoader.loadInstance("com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot")); | |||
// Add `StatisticSlot` | |||
chain.addLast((AbstractLinkedProcessorSlot<?>) spiLoader.loadInstance(StatisticSlot.class)); | |||
// Add `FlowSlot` | |||
chain.addLast((AbstractLinkedProcessorSlot<?>) spiLoader.loadInstance(FlowSlot.class)); | |||
// Add `DegradeSlot` | |||
// Test for `DemoDegradeRuleApplication` | |||
// If we don't add `DegradeSlot`, the demo will not be blocked by `DegradeException` | |||
// If it's added, we can see the expected DegradeException | |||
// chain.addLast((AbstractLinkedProcessorSlot<?>) spiLoader.loadInstance(DegradeSlot.class)); | |||
return chain; | |||
} | |||
*/ | |||
} |
@@ -0,0 +1,2 @@ | |||
# Custom SlotChainBuilder to build slot chain | |||
com.alibaba.csp.sentinel.demo.slotchain.DemoSlotChainBuilder |