Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -57,12 +57,12 @@ public final class Constants { | |||
* Global ROOT statistic node that represents the universal parent node. | |||
*/ | |||
public final static DefaultNode ROOT = new EntranceNode(new StringResourceWrapper(ROOT_ID, EntryType.IN), | |||
new ClusterNode()); | |||
new ClusterNode(ROOT_ID, ResourceTypeConstants.COMMON)); | |||
/** | |||
* Global statistic node for inbound traffic. Usually used for {@link SystemRule} checking. | |||
*/ | |||
public final static ClusterNode ENTRY_NODE = new ClusterNode(); | |||
public final static ClusterNode ENTRY_NODE = new ClusterNode(TOTAL_IN_RESOURCE_NAME, ResourceTypeConstants.COMMON); | |||
/** | |||
* Response time that exceeds TIME_DROP_VALVE will be calculated as TIME_DROP_VALVE. Default value is 4900 ms. | |||
@@ -71,7 +71,7 @@ public class CtSph implements Sph { | |||
} | |||
if (context == null) { | |||
// Using default context. | |||
context = MyContextUtil.myEnter(Constants.CONTEXT_DEFAULT_NAME, "", resourceWrapper.getType()); | |||
context = InternalContextUtil.internalEnter(Constants.CONTEXT_DEFAULT_NAME); | |||
} | |||
// Global switch is turned off, so no rule checking will be done. | |||
@@ -125,7 +125,7 @@ public class CtSph implements Sph { | |||
if (context == null) { | |||
// Using default context. | |||
context = MyContextUtil.myEnter(Constants.CONTEXT_DEFAULT_NAME, "", resourceWrapper.getType()); | |||
context = InternalContextUtil.internalEnter(Constants.CONTEXT_DEFAULT_NAME); | |||
} | |||
// Global switch is close, no rule checking will do. | |||
@@ -245,8 +245,12 @@ public class CtSph implements Sph { | |||
/** | |||
* This class is used for skip context name checking. | |||
*/ | |||
private final static class MyContextUtil extends ContextUtil { | |||
static Context myEnter(String name, String origin, EntryType type) { | |||
private final static class InternalContextUtil extends ContextUtil { | |||
static Context internalEnter(String name) { | |||
return trueEnter(name, ""); | |||
} | |||
static Context internalEnter(String name, String origin) { | |||
return trueEnter(name, origin); | |||
} | |||
} | |||
@@ -329,4 +333,24 @@ public class CtSph implements Sph { | |||
StringResourceWrapper resource = new StringResourceWrapper(name, type); | |||
return entryWithPriority(resource, count, prioritized, args); | |||
} | |||
@Override | |||
public Entry entryWithType(String name, int resourceType, EntryType entryType, int count, Object[] args) | |||
throws BlockException { | |||
return entryWithType(name, resourceType, entryType, count, false, args); | |||
} | |||
@Override | |||
public Entry entryWithType(String name, int resourceType, EntryType entryType, int count, boolean prioritized, | |||
Object[] args) throws BlockException { | |||
StringResourceWrapper resource = new StringResourceWrapper(name, entryType, resourceType); | |||
return entryWithPriority(resource, count, prioritized, args); | |||
} | |||
@Override | |||
public AsyncEntry asyncEntryWithType(String name, int resourceType, EntryType entryType, int count, | |||
boolean prioritized, Object[] args) throws BlockException { | |||
StringResourceWrapper resource = new StringResourceWrapper(name, entryType, resourceType); | |||
return asyncEntryWithPriorityInternal(resource, count, prioritized, args); | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
/* | |||
* Copyright 1999-2019 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 | |||
* | |||
* https://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; | |||
/** | |||
* @author Eric Zhao | |||
* @since 1.7.0 | |||
*/ | |||
public final class ResourceTypeConstants { | |||
public static final int COMMON = 0; | |||
public static final int COMMON_WEB = 1; | |||
public static final int COMMON_RPC = 2; | |||
public static final int COMMON_API_GATEWAY = 3; | |||
public static final int COMMON_DB_SQL = 4; | |||
private ResourceTypeConstants() {} | |||
} |
@@ -29,7 +29,7 @@ import com.alibaba.csp.sentinel.slots.block.BlockException; | |||
* @author leyou | |||
* @author Eric Zhao | |||
*/ | |||
public interface Sph { | |||
public interface Sph extends SphResourceTypeSupport { | |||
/** | |||
* Create a protected resource. | |||
@@ -0,0 +1,69 @@ | |||
/* | |||
* Copyright 1999-2019 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 | |||
* | |||
* https://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; | |||
import com.alibaba.csp.sentinel.slots.block.BlockException; | |||
/** | |||
* @author Eric Zhao | |||
* @since 1.7.0 | |||
*/ | |||
public interface SphResourceTypeSupport { | |||
/** | |||
* Create a protected resource with provided classification. | |||
* | |||
* @param name the unique name of the protected resource | |||
* @param resourceType the classification of the resource | |||
* @param entryType the traffic entry type (IN/OUT) of the resource | |||
* @param count tokens required | |||
* @param args extra parameters | |||
* @return new entry of the resource | |||
* @throws BlockException if the block criteria is met | |||
*/ | |||
Entry entryWithType(String name, int resourceType, EntryType entryType, int count, Object[] args) | |||
throws BlockException; | |||
/** | |||
* Create a protected resource with provided classification. | |||
* | |||
* @param name the unique name of the protected resource | |||
* @param resourceType the classification of the resource | |||
* @param entryType the traffic entry type (IN/OUT) of the resource | |||
* @param count tokens required | |||
* @param prioritized whether the entry is prioritized | |||
* @param args extra parameters | |||
* @return new entry of the resource | |||
* @throws BlockException if the block criteria is met | |||
*/ | |||
Entry entryWithType(String name, int resourceType, EntryType entryType, int count, boolean prioritized, | |||
Object[] args) throws BlockException; | |||
/** | |||
* Create an asynchronous resource with provided classification. | |||
* | |||
* @param name the unique name of the protected resource | |||
* @param resourceType the classification of the resource | |||
* @param entryType the traffic entry type (IN/OUT) of the resource | |||
* @param count tokens required | |||
* @param prioritized whether the entry is prioritized | |||
* @param args extra parameters | |||
* @return new entry of the resource | |||
* @throws BlockException if the block criteria is met | |||
*/ | |||
AsyncEntry asyncEntryWithType(String name, int resourceType, EntryType entryType, int count, boolean prioritized, | |||
Object[] args) throws BlockException; | |||
} |
@@ -76,6 +76,8 @@ public class SphU { | |||
private static final Object[] OBJECTS0 = new Object[0]; | |||
private SphU() {} | |||
/** | |||
* Checking all {@link Rule}s about the resource. | |||
* | |||
@@ -246,7 +248,7 @@ public class SphU { | |||
/** | |||
* Checking all {@link Rule}s related the resource. The entry is prioritized. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param name the unique name for the protected resource | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded. | |||
* @since 1.4.0 | |||
*/ | |||
@@ -257,14 +259,97 @@ public class SphU { | |||
/** | |||
* Checking all {@link Rule}s related the resource. The entry is prioritized. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @param name the unique name for the protected resource | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded. | |||
* @since 1.4.0 | |||
*/ | |||
public static Entry entryWithPriority(String name, EntryType type) throws BlockException { | |||
return Env.sph.entryWithPriority(name, type, 1, true); | |||
} | |||
/** | |||
* Record statistics and check all rules of the resource. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param resourceType classification of the resource (e.g. Web or RPC) | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded | |||
* @since 1.7.0 | |||
*/ | |||
public static Entry entry(String name, int resourceType, EntryType type) throws BlockException { | |||
return Env.sph.entryWithType(name, resourceType, type, 1, OBJECTS0); | |||
} | |||
/** | |||
* Record statistics and check all rules of the resource. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @param resourceType classification of the resource (e.g. Web or RPC) | |||
* @param args extra parameters. | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded | |||
* @since 1.7.0 | |||
*/ | |||
public static Entry entry(String name, int resourceType, EntryType type, Object[] args) | |||
throws BlockException { | |||
return Env.sph.entryWithType(name, resourceType, type, 1, args); | |||
} | |||
/** | |||
* Record statistics and check all rules of the resource. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @param resourceType classification of the resource (e.g. Web or RPC) | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded | |||
* @since 1.7.0 | |||
*/ | |||
public static AsyncEntry asyncEntry(String name, int resourceType, EntryType type) | |||
throws BlockException { | |||
return Env.sph.asyncEntryWithType(name, resourceType, type, 1, false, OBJECTS0); | |||
} | |||
/** | |||
* Record statistics and check all rules of the resource. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @param resourceType classification of the resource (e.g. Web or RPC) | |||
* @param args extra parameters | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded | |||
* @since 1.7.0 | |||
*/ | |||
public static AsyncEntry asyncEntry(String name, int resourceType, EntryType type, Object[] args) | |||
throws BlockException { | |||
return Env.sph.asyncEntryWithType(name, resourceType, type, 1, false, args); | |||
} | |||
/** | |||
* Record statistics and check all rules of the resource. | |||
* | |||
* @param name the unique name for the protected resource | |||
* @param type the resource is an inbound or an outbound method. This is used | |||
* to mark whether it can be blocked when the system is unstable, | |||
* only inbound traffic could be blocked by {@link SystemRule} | |||
* @param resourceType classification of the resource (e.g. Web or RPC) | |||
* @param acquireCount tokens required | |||
* @param args extra parameters | |||
* @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded | |||
* @since 1.7.0 | |||
*/ | |||
public static AsyncEntry asyncEntry(String name, int resourceType, EntryType type, int acquireCount, | |||
Object[] args) throws BlockException { | |||
return Env.sph.asyncEntryWithType(name, resourceType, type, acquireCount, false, args); | |||
} | |||
} |
@@ -40,6 +40,12 @@ public @interface SentinelResource { | |||
*/ | |||
EntryType entryType() default EntryType.OUT; | |||
/** | |||
* @return the classification (type) of the resource | |||
* @since 1.7.0 | |||
*/ | |||
int resourceType() default 0; | |||
/** | |||
* @return name of the block exception function, empty by default | |||
*/ | |||
@@ -19,8 +19,10 @@ import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.concurrent.locks.ReentrantLock; | |||
import com.alibaba.csp.sentinel.ResourceTypeConstants; | |||
import com.alibaba.csp.sentinel.context.ContextUtil; | |||
import com.alibaba.csp.sentinel.slots.block.BlockException; | |||
import com.alibaba.csp.sentinel.util.AssertUtil; | |||
/** | |||
* <p> | |||
@@ -42,6 +44,19 @@ import com.alibaba.csp.sentinel.slots.block.BlockException; | |||
*/ | |||
public class ClusterNode extends StatisticNode { | |||
private final String name; | |||
private final int resourceType; | |||
public ClusterNode(String name) { | |||
this(name, ResourceTypeConstants.COMMON); | |||
} | |||
public ClusterNode(String name, int resourceType) { | |||
AssertUtil.notEmpty(name, "name cannot be empty"); | |||
this.name = name; | |||
this.resourceType = resourceType; | |||
} | |||
/** | |||
* <p>The origin map holds the pair: (origin, originNode) for one specific resource.</p> | |||
* <p> | |||
@@ -50,10 +65,30 @@ public class ClusterNode extends StatisticNode { | |||
* at the very beginning while concurrent map will hold the lock all the time. | |||
* </p> | |||
*/ | |||
private Map<String, StatisticNode> originCountMap = new HashMap<String, StatisticNode>(); | |||
private Map<String, StatisticNode> originCountMap = new HashMap<>(); | |||
private final ReentrantLock lock = new ReentrantLock(); | |||
/** | |||
* Get resource name of the resource node. | |||
* | |||
* @return resource name | |||
* @since 1.7.0 | |||
*/ | |||
public String getName() { | |||
return name; | |||
} | |||
/** | |||
* Get classification (type) of the resource. | |||
* | |||
* @return resource type | |||
* @since 1.7.0 | |||
*/ | |||
public int getResourceType() { | |||
return resourceType; | |||
} | |||
/** | |||
* <p>Get {@link Node} of the specific origin. Usually the origin is the Service Consumer's app name.</p> | |||
* <p>If the origin node for given origin is absent, then a new {@link StatisticNode} | |||
@@ -84,7 +119,7 @@ public class ClusterNode extends StatisticNode { | |||
return statisticNode; | |||
} | |||
public synchronized Map<String, StatisticNode> getOriginCountMap() { | |||
public Map<String, StatisticNode> getOriginCountMap() { | |||
return originCountMap; | |||
} | |||
@@ -27,6 +27,13 @@ import java.util.Date; | |||
*/ | |||
public class MetricNode { | |||
private String resource; | |||
/** | |||
* Resource classification (e.g. SQL or RPC) | |||
* @since 1.7.0 | |||
*/ | |||
private int classification; | |||
private long timestamp; | |||
private long passQps; | |||
private long blockQps; | |||
@@ -38,8 +45,10 @@ public class MetricNode { | |||
* @since 1.5.0 | |||
*/ | |||
private long occupiedPassQps; | |||
private String resource; | |||
/** | |||
* @since 1.7.0 | |||
*/ | |||
private int concurrency; | |||
public long getTimestamp() { | |||
return timestamp; | |||
@@ -105,12 +114,38 @@ public class MetricNode { | |||
this.resource = resource; | |||
} | |||
public int getClassification() { | |||
return classification; | |||
} | |||
public MetricNode setClassification(int classification) { | |||
this.classification = classification; | |||
return this; | |||
} | |||
public int getConcurrency() { | |||
return concurrency; | |||
} | |||
public MetricNode setConcurrency(int concurrency) { | |||
this.concurrency = concurrency; | |||
return this; | |||
} | |||
@Override | |||
public String toString() { | |||
return "MetricNode{" + "timestamp=" + timestamp + ", passQps=" + passQps + ", blockQps=" + blockQps | |||
+ ", successQps=" + successQps + ", exceptionQps=" + exceptionQps + ", rt=" + rt | |||
+ ", occupiedPassQps=" + occupiedPassQps + ", resource='" | |||
+ resource + '\'' + '}'; | |||
return "MetricNode{" + | |||
"resource='" + resource + '\'' + | |||
", classification=" + classification + | |||
", timestamp=" + timestamp + | |||
", passQps=" + passQps + | |||
", blockQps=" + blockQps + | |||
", successQps=" + successQps + | |||
", exceptionQps=" + exceptionQps + | |||
", rt=" + rt + | |||
", concurrency=" + concurrency + | |||
", occupiedPassQps=" + occupiedPassQps + | |||
'}'; | |||
} | |||
/** | |||
@@ -132,7 +167,9 @@ public class MetricNode { | |||
sb.append(successQps).append("|"); | |||
sb.append(exceptionQps).append("|"); | |||
sb.append(rt).append("|"); | |||
sb.append(occupiedPassQps); | |||
sb.append(occupiedPassQps).append("|"); | |||
sb.append(concurrency).append("|"); | |||
sb.append(classification); | |||
return sb.toString(); | |||
} | |||
@@ -152,9 +189,15 @@ public class MetricNode { | |||
node.setSuccessQps(Long.parseLong(strs[4])); | |||
node.setExceptionQps(Long.parseLong(strs[5])); | |||
node.setRt(Long.parseLong(strs[6])); | |||
if (strs.length == 8) { | |||
if (strs.length >= 8) { | |||
node.setOccupiedPassQps(Long.parseLong(strs[7])); | |||
} | |||
if (strs.length >= 9) { | |||
node.setConcurrency(Integer.parseInt(strs[8])); | |||
} | |||
if (strs.length == 10) { | |||
node.setClassification(Integer.parseInt(strs[9])); | |||
} | |||
return node; | |||
} | |||
@@ -180,7 +223,9 @@ public class MetricNode { | |||
sb.append(getSuccessQps()).append("|"); | |||
sb.append(getExceptionQps()).append("|"); | |||
sb.append(getRt()).append("|"); | |||
sb.append(getOccupiedPassQps()); | |||
sb.append(getOccupiedPassQps()).append("|"); | |||
sb.append(concurrency).append("|"); | |||
sb.append(classification); | |||
sb.append('\n'); | |||
return sb.toString(); | |||
} | |||
@@ -202,9 +247,15 @@ public class MetricNode { | |||
node.setSuccessQps(Long.parseLong(strs[5])); | |||
node.setExceptionQps(Long.parseLong(strs[6])); | |||
node.setRt(Long.parseLong(strs[7])); | |||
if (strs.length == 9) { | |||
if (strs.length >= 9) { | |||
node.setOccupiedPassQps(Long.parseLong(strs[8])); | |||
} | |||
if (strs.length >= 10) { | |||
node.setConcurrency(Integer.parseInt(strs[9])); | |||
} | |||
if (strs.length == 11) { | |||
node.setClassification(Integer.parseInt(strs[10])); | |||
} | |||
return node; | |||
} | |||
@@ -38,14 +38,13 @@ public class MetricTimerListener implements Runnable { | |||
@Override | |||
public void run() { | |||
Map<Long, List<MetricNode>> maps = new TreeMap<Long, List<MetricNode>>(); | |||
Map<Long, List<MetricNode>> maps = new TreeMap<>(); | |||
for (Entry<ResourceWrapper, ClusterNode> e : ClusterBuilderSlot.getClusterNodeMap().entrySet()) { | |||
String name = e.getKey().getName(); | |||
ClusterNode node = e.getValue(); | |||
Map<Long, MetricNode> metrics = node.metrics(); | |||
aggregate(maps, metrics, name); | |||
aggregate(maps, metrics, node); | |||
} | |||
aggregate(maps, Constants.ENTRY_NODE.metrics(), Constants.TOTAL_IN_RESOURCE_NAME); | |||
aggregate(maps, Constants.ENTRY_NODE.metrics(), Constants.ENTRY_NODE); | |||
if (!maps.isEmpty()) { | |||
for (Entry<Long, List<MetricNode>> entry : maps.entrySet()) { | |||
try { | |||
@@ -57,11 +56,12 @@ public class MetricTimerListener implements Runnable { | |||
} | |||
} | |||
private void aggregate(Map<Long, List<MetricNode>> maps, Map<Long, MetricNode> metrics, String resourceName) { | |||
private void aggregate(Map<Long, List<MetricNode>> maps, Map<Long, MetricNode> metrics, ClusterNode node) { | |||
for (Entry<Long, MetricNode> entry : metrics.entrySet()) { | |||
long time = entry.getKey(); | |||
MetricNode metricNode = entry.getValue(); | |||
metricNode.setResource(resourceName); | |||
metricNode.setResource(node.getName()); | |||
metricNode.setClassification(node.getResourceType()); | |||
if (maps.get(time) == null) { | |||
maps.put(time, new ArrayList<MetricNode>()); | |||
} | |||
@@ -18,6 +18,7 @@ package com.alibaba.csp.sentinel.slotchain; | |||
import java.lang.reflect.Method; | |||
import com.alibaba.csp.sentinel.EntryType; | |||
import com.alibaba.csp.sentinel.ResourceTypeConstants; | |||
import com.alibaba.csp.sentinel.util.IdUtil; | |||
import com.alibaba.csp.sentinel.util.MethodUtil; | |||
@@ -28,17 +29,15 @@ import com.alibaba.csp.sentinel.util.MethodUtil; | |||
*/ | |||
public class MethodResourceWrapper extends ResourceWrapper { | |||
private transient Method method; | |||
private final transient Method method; | |||
public MethodResourceWrapper(Method method, EntryType type) { | |||
this.method = method; | |||
this.name = MethodUtil.resolveMethodName(method); | |||
this.type = type; | |||
public MethodResourceWrapper(Method method, EntryType e) { | |||
this(method, e, ResourceTypeConstants.COMMON); | |||
} | |||
@Override | |||
public String getName() { | |||
return name; | |||
public MethodResourceWrapper(Method method, EntryType e, int resType) { | |||
super(MethodUtil.resolveMethodName(method), e, resType); | |||
this.method = method; | |||
} | |||
public Method getMethod() { | |||
@@ -51,8 +50,11 @@ public class MethodResourceWrapper extends ResourceWrapper { | |||
} | |||
@Override | |||
public EntryType getType() { | |||
return type; | |||
public String toString() { | |||
return "MethodResourceWrapper{" + | |||
"name='" + name + '\'' + | |||
", entryType=" + entryType + | |||
", resourceType=" + resourceType + | |||
'}'; | |||
} | |||
} |
@@ -16,28 +16,64 @@ | |||
package com.alibaba.csp.sentinel.slotchain; | |||
import com.alibaba.csp.sentinel.EntryType; | |||
import com.alibaba.csp.sentinel.util.AssertUtil; | |||
/** | |||
* A wrapper of resource name and {@link EntryType}. | |||
* A wrapper of resource name and type. | |||
* | |||
* @author qinan.qn | |||
* @author jialiang.linjl | |||
* @author Eric Zhao | |||
*/ | |||
public abstract class ResourceWrapper { | |||
protected String name; | |||
protected EntryType type = EntryType.OUT; | |||
protected final String name; | |||
public abstract String getName(); | |||
protected final EntryType entryType; | |||
protected final int resourceType; | |||
public abstract String getShowName(); | |||
public ResourceWrapper(String name, EntryType entryType, int resourceType) { | |||
AssertUtil.notEmpty(name, "resource name cannot be empty"); | |||
AssertUtil.notNull(entryType, "entryType cannot be null"); | |||
this.name = name; | |||
this.entryType = entryType; | |||
this.resourceType = resourceType; | |||
} | |||
/** | |||
* Get the resource name. | |||
* | |||
* @return the resource name | |||
*/ | |||
public String getName() { | |||
return name; | |||
} | |||
/** | |||
* Get {@link EntryType} of this wrapper. | |||
* | |||
* @return {@link EntryType} of this wrapper. | |||
*/ | |||
public abstract EntryType getType(); | |||
public EntryType getEntryType() { | |||
return entryType; | |||
} | |||
/** | |||
* Get the classification of this resource. | |||
* | |||
* @return the classification of this resource | |||
* @since 1.7.0 | |||
*/ | |||
public int getResourceType() { | |||
return resourceType; | |||
} | |||
/** | |||
* Get the beautified resource name to be showed. | |||
* | |||
* @return the beautified resource name | |||
*/ | |||
public abstract String getShowName(); | |||
/** | |||
* Only {@link #getName()} is considered. | |||
@@ -16,26 +16,22 @@ | |||
package com.alibaba.csp.sentinel.slotchain; | |||
import com.alibaba.csp.sentinel.EntryType; | |||
import com.alibaba.csp.sentinel.ResourceTypeConstants; | |||
/** | |||
* Common resource wrapper. | |||
* Common string resource wrapper. | |||
* | |||
* @author qinan.qn | |||
* @author jialiang.linjl | |||
*/ | |||
public class StringResourceWrapper extends ResourceWrapper { | |||
public StringResourceWrapper(String name, EntryType type) { | |||
if (name == null) { | |||
throw new IllegalArgumentException("Resource name cannot be null"); | |||
} | |||
this.name = name; | |||
this.type = type; | |||
public StringResourceWrapper(String name, EntryType e) { | |||
super(name, e, ResourceTypeConstants.COMMON); | |||
} | |||
@Override | |||
public String getName() { | |||
return name; | |||
public StringResourceWrapper(String name, EntryType e, int resType) { | |||
super(name, e, resType); | |||
} | |||
@Override | |||
@@ -43,16 +39,12 @@ public class StringResourceWrapper extends ResourceWrapper { | |||
return name; | |||
} | |||
@Override | |||
public EntryType getType() { | |||
return type; | |||
} | |||
@Override | |||
public String toString() { | |||
return "StringResourceWrapper{" + | |||
"name='" + name + '\'' + | |||
", type=" + type + | |||
", entryType=" + entryType + | |||
", resourceType=" + resourceType + | |||
'}'; | |||
} | |||
} |
@@ -78,7 +78,7 @@ public class ClusterBuilderSlot extends AbstractLinkedProcessorSlot<DefaultNode> | |||
synchronized (lock) { | |||
if (clusterNode == null) { | |||
// Create the cluster node. | |||
clusterNode = new ClusterNode(); | |||
clusterNode = new ClusterNode(resourceWrapper.getName(), resourceWrapper.getResourceType()); | |||
HashMap<ResourceWrapper, ClusterNode> newMap = new HashMap<>(Math.max(clusterNodeMap.size(), 16)); | |||
newMap.putAll(clusterNodeMap); | |||
newMap.put(node.getId(), clusterNode); | |||
@@ -65,7 +65,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
context.getCurEntry().getOriginNode().addPassRequest(count); | |||
} | |||
if (resourceWrapper.getType() == EntryType.IN) { | |||
if (resourceWrapper.getEntryType() == EntryType.IN) { | |||
// Add count for global inbound entry node for global statistics. | |||
Constants.ENTRY_NODE.increaseThreadNum(); | |||
Constants.ENTRY_NODE.addPassRequest(count); | |||
@@ -82,7 +82,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
context.getCurEntry().getOriginNode().increaseThreadNum(); | |||
} | |||
if (resourceWrapper.getType() == EntryType.IN) { | |||
if (resourceWrapper.getEntryType() == EntryType.IN) { | |||
// Add count for global inbound entry node for global statistics. | |||
Constants.ENTRY_NODE.increaseThreadNum(); | |||
} | |||
@@ -100,7 +100,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
context.getCurEntry().getOriginNode().increaseBlockQps(count); | |||
} | |||
if (resourceWrapper.getType() == EntryType.IN) { | |||
if (resourceWrapper.getEntryType() == EntryType.IN) { | |||
// Add count for global inbound entry node for global statistics. | |||
Constants.ENTRY_NODE.increaseBlockQps(count); | |||
} | |||
@@ -121,7 +121,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
context.getCurEntry().getOriginNode().increaseExceptionQps(count); | |||
} | |||
if (resourceWrapper.getType() == EntryType.IN) { | |||
if (resourceWrapper.getEntryType() == EntryType.IN) { | |||
Constants.ENTRY_NODE.increaseExceptionQps(count); | |||
} | |||
throw e; | |||
@@ -151,7 +151,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> { | |||
context.getCurEntry().getOriginNode().decreaseThreadNum(); | |||
} | |||
if (resourceWrapper.getType() == EntryType.IN) { | |||
if (resourceWrapper.getEntryType() == EntryType.IN) { | |||
Constants.ENTRY_NODE.addRtAndSuccess(rt, count); | |||
Constants.ENTRY_NODE.decreaseThreadNum(); | |||
} | |||
@@ -297,7 +297,7 @@ public final class SystemRuleManager { | |||
} | |||
// for inbound traffic only | |||
if (resourceWrapper.getType() != EntryType.IN) { | |||
if (resourceWrapper.getEntryType() != EntryType.IN) { | |||
return; | |||
} | |||
@@ -41,7 +41,7 @@ public class CtSphTest { | |||
Entry entry = null; | |||
try { | |||
if (async) { | |||
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getType(), 1); | |||
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getEntryType(), 1); | |||
} else { | |||
entry = ctSph.entry(resourceWrapper, 1); | |||
} | |||
@@ -80,7 +80,7 @@ public class CtSphTest { | |||
if (!async) { | |||
entry = ctSph.entry(resourceWrapper, 1); | |||
} else { | |||
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getType(), 1); | |||
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getEntryType(), 1); | |||
Context asyncContext = ((AsyncEntry)entry).getAsyncContext(); | |||
assertTrue(ContextUtil.isDefaultContext(asyncContext)); | |||
assertTrue(asyncContext.isAsync()); | |||
@@ -127,7 +127,7 @@ public class CtSphTest { | |||
AsyncEntry asyncEntry = null; | |||
try { | |||
entry = ctSph.entry(resourceWrapperA, 1); | |||
asyncEntry = ctSph.asyncEntry(resourceNameB, resourceWrapperB.getType(), 1); | |||
asyncEntry = ctSph.asyncEntry(resourceNameB, resourceWrapperB.getEntryType(), 1); | |||
} catch (BlockException ex) { | |||
fail("Unexpected blocked: " + ex.getClass().getCanonicalName()); | |||
} finally { | |||
@@ -63,7 +63,7 @@ public class SphOTest { | |||
try { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.OUT); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.OUT); | |||
} finally { | |||
SphO.exit(2); | |||
} | |||
@@ -78,7 +78,7 @@ public class SphOTest { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), | |||
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryCount()")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.OUT); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.OUT); | |||
} finally { | |||
SphO.exit(2); | |||
} | |||
@@ -91,7 +91,7 @@ public class SphOTest { | |||
try { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN); | |||
} finally { | |||
SphO.exit(); | |||
} | |||
@@ -106,7 +106,7 @@ public class SphOTest { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), | |||
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryType()")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN); | |||
} finally { | |||
SphO.exit(); | |||
} | |||
@@ -119,7 +119,7 @@ public class SphOTest { | |||
try { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN); | |||
} finally { | |||
SphO.exit(2); | |||
} | |||
@@ -134,7 +134,7 @@ public class SphOTest { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), | |||
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryTypeCount()")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN); | |||
} finally { | |||
SphO.exit(2); | |||
} | |||
@@ -147,7 +147,7 @@ public class SphOTest { | |||
try { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN); | |||
} finally { | |||
SphO.exit(2, "hello1", "hello2"); | |||
} | |||
@@ -162,7 +162,7 @@ public class SphOTest { | |||
assertTrue(StringUtil.equalsIgnoreCase( | |||
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), | |||
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryAll()")); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); | |||
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN); | |||
} finally { | |||
SphO.exit(2, "hello1", "hello2"); | |||
} | |||
@@ -38,7 +38,7 @@ public class SphUTest { | |||
assertNotNull(e); | |||
assertEquals(e.resourceWrapper.getName(), "resourceName"); | |||
assertEquals(e.resourceWrapper.getType(), EntryType.OUT); | |||
assertEquals(e.resourceWrapper.getEntryType(), EntryType.OUT); | |||
assertEquals(ContextUtil.getContext().getName(), Constants.CONTEXT_DEFAULT_NAME); | |||
e.exit(); | |||
@@ -53,7 +53,7 @@ public class SphUTest { | |||
assertTrue(StringUtil | |||
.equalsIgnoreCase(e.resourceWrapper.getName(), | |||
"com.alibaba.csp.sentinel.SphUTest:testMethodEntryNormal()")); | |||
assertEquals(e.resourceWrapper.getType(), EntryType.OUT); | |||
assertEquals(e.resourceWrapper.getEntryType(), EntryType.OUT); | |||
assertEquals(ContextUtil.getContext().getName(), Constants.CONTEXT_DEFAULT_NAME); | |||
e.exit(); | |||
@@ -78,7 +78,7 @@ public class SphUTest { | |||
assertNotNull(e); | |||
assertEquals("resourceName", e.resourceWrapper.getName()); | |||
assertEquals(e.resourceWrapper.getType(), EntryType.OUT); | |||
assertEquals(e.resourceWrapper.getEntryType(), EntryType.OUT); | |||
assertEquals(ContextUtil.getContext().getName(), Constants.CONTEXT_DEFAULT_NAME); | |||
e.exit(2); | |||
@@ -93,7 +93,7 @@ public class SphUTest { | |||
assertTrue(StringUtil | |||
.equalsIgnoreCase(e.resourceWrapper.getName(), | |||
"com.alibaba.csp.sentinel.SphUTest:testMethodEntryNormal()")); | |||
assertEquals(e.resourceWrapper.getType(), EntryType.OUT); | |||
assertEquals(e.resourceWrapper.getEntryType(), EntryType.OUT); | |||
e.exit(2); | |||
} | |||
@@ -102,7 +102,7 @@ public class SphUTest { | |||
public void testStringEntryType() throws BlockException { | |||
Entry e = SphU.entry("resourceName", EntryType.IN); | |||
assertSame(e.resourceWrapper.getType(), EntryType.IN); | |||
assertSame(e.resourceWrapper.getEntryType(), EntryType.IN); | |||
e.exit(); | |||
} | |||
@@ -112,7 +112,7 @@ public class SphUTest { | |||
Method method = SphUTest.class.getMethod("testMethodEntryNormal"); | |||
Entry e = SphU.entry(method, EntryType.IN); | |||
assertSame(e.resourceWrapper.getType(), EntryType.IN); | |||
assertSame(e.resourceWrapper.getEntryType(), EntryType.IN); | |||
e.exit(); | |||
} | |||
@@ -121,7 +121,7 @@ public class SphUTest { | |||
public void testStringEntryCountType() throws BlockException { | |||
Entry e = SphU.entry("resourceName", EntryType.IN, 2); | |||
assertSame(e.resourceWrapper.getType(), EntryType.IN); | |||
assertSame(e.resourceWrapper.getEntryType(), EntryType.IN); | |||
e.exit(2); | |||
} | |||
@@ -131,7 +131,7 @@ public class SphUTest { | |||
Method method = SphUTest.class.getMethod("testMethodEntryNormal"); | |||
Entry e = SphU.entry(method, EntryType.IN, 2); | |||
assertSame(e.resourceWrapper.getType(), EntryType.IN); | |||
assertSame(e.resourceWrapper.getEntryType(), EntryType.IN); | |||
e.exit(); | |||
} | |||
@@ -141,7 +141,7 @@ public class SphUTest { | |||
final String arg0 = "foo"; | |||
final String arg1 = "baz"; | |||
Entry e = SphU.entry("resourceName", EntryType.IN, 2, arg0, arg1); | |||
assertSame(e.resourceWrapper.getType(), EntryType.IN); | |||
assertSame(e.resourceWrapper.getEntryType(), EntryType.IN); | |||
e.exit(2, arg0, arg1); | |||
} | |||
@@ -153,7 +153,7 @@ public class SphUTest { | |||
Method method = SphUTest.class.getMethod("testMethodEntryNormal"); | |||
Entry e = SphU.entry(method, EntryType.IN, 2, arg0, arg1); | |||
assertSame(e.resourceWrapper.getType(), EntryType.IN); | |||
assertSame(e.resourceWrapper.getEntryType(), EntryType.IN); | |||
e.exit(2, arg0, arg1); | |||
} | |||
@@ -41,7 +41,7 @@ public class ClusterNodeTest { | |||
@Test | |||
public void testGetOrCreateOriginNodeSingleThread() { | |||
ClusterNode clusterNode = new ClusterNode(); | |||
ClusterNode clusterNode = new ClusterNode("test"); | |||
String origin1 = "origin1"; | |||
Node originNode1 = clusterNode.getOrCreateOriginNode(origin1); | |||
@@ -74,7 +74,7 @@ public class ClusterNodeTest { | |||
final int testTimes = 10; | |||
for (int times = 0; times < testTimes; times++) { | |||
final ClusterNode clusterNode = new ClusterNode(); | |||
final ClusterNode clusterNode = new ClusterNode("test"); | |||
// Store all distinct nodes by calling ClusterNode#getOrCreateOriginNode. | |||
// Here we need a thread-safe concurrent set (created from ConcurrentHashMap). | |||
@@ -130,7 +130,7 @@ public class ClusterNodeTest { | |||
@Test | |||
public void testTraceException() { | |||
ClusterNode clusterNode = new ClusterNode(); | |||
ClusterNode clusterNode = new ClusterNode("test"); | |||
Exception exception = new RuntimeException("test"); | |||
@@ -0,0 +1,37 @@ | |||
/* | |||
* 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.node.metric; | |||
import com.alibaba.csp.sentinel.ResourceTypeConstants; | |||
import org.junit.Test; | |||
import static org.junit.Assert.*; | |||
/** | |||
* @author Eric Zhao | |||
*/ | |||
public class MetricNodeTest { | |||
@Test | |||
public void testFromFatString() { | |||
String line = "1564382218000|2019-07-29 14:36:58|/foo/*|1|0|1|0|0|0|2|1"; | |||
MetricNode node = MetricNode.fromFatString(line); | |||
assertEquals(ResourceTypeConstants.COMMON_WEB, node.getClassification()); | |||
assertEquals(2, node.getConcurrency()); | |||
assertEquals(1, node.getSuccessQps()); | |||
} | |||
} |