Support classification for Sentinel resources

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
Eric Zhao 2019-11-06 16:10:25 +08:00
parent 9d514d5036
commit 6bb2de8750
21 changed files with 462 additions and 94 deletions

View File

@ -57,12 +57,12 @@ public final class Constants {
* Global ROOT statistic node that represents the universal parent node. * Global ROOT statistic node that represents the universal parent node.
*/ */
public final static DefaultNode ROOT = new EntranceNode(new StringResourceWrapper(ROOT_ID, EntryType.IN), 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. * 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. * Response time that exceeds TIME_DROP_VALVE will be calculated as TIME_DROP_VALVE. Default value is 4900 ms.

View File

@ -71,7 +71,7 @@ public class CtSph implements Sph {
} }
if (context == null) { if (context == null) {
// Using default context. // 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. // Global switch is turned off, so no rule checking will be done.
@ -125,7 +125,7 @@ public class CtSph implements Sph {
if (context == null) { if (context == null) {
// Using default context. // 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. // 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. * This class is used for skip context name checking.
*/ */
private final static class MyContextUtil extends ContextUtil { private final static class InternalContextUtil extends ContextUtil {
static Context myEnter(String name, String origin, EntryType type) { static Context internalEnter(String name) {
return trueEnter(name, "");
}
static Context internalEnter(String name, String origin) {
return trueEnter(name, origin); return trueEnter(name, origin);
} }
} }
@ -329,4 +333,24 @@ public class CtSph implements Sph {
StringResourceWrapper resource = new StringResourceWrapper(name, type); StringResourceWrapper resource = new StringResourceWrapper(name, type);
return entryWithPriority(resource, count, prioritized, args); 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);
}
} }

View File

@ -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() {}
}

View File

@ -29,7 +29,7 @@ import com.alibaba.csp.sentinel.slots.block.BlockException;
* @author leyou * @author leyou
* @author Eric Zhao * @author Eric Zhao
*/ */
public interface Sph { public interface Sph extends SphResourceTypeSupport {
/** /**
* Create a protected resource. * Create a protected resource.

View File

@ -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;
}

View File

@ -76,6 +76,8 @@ public class SphU {
private static final Object[] OBJECTS0 = new Object[0]; private static final Object[] OBJECTS0 = new Object[0];
private SphU() {}
/** /**
* Checking all {@link Rule}s about the resource. * 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. * 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. * @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded.
* @since 1.4.0 * @since 1.4.0
*/ */
@ -257,14 +259,97 @@ public class SphU {
/** /**
* Checking all {@link Rule}s related the resource. The entry is prioritized. * 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
* @param type the resource is an inbound or an outbound method. This is used * @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, * to mark whether it can be blocked when the system is unstable,
* only inbound traffic could be blocked by {@link SystemRule} * 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. * @throws BlockException if the block criteria is met, eg. when any rule's threshold is exceeded.
* @since 1.4.0 * @since 1.4.0
*/ */
public static Entry entryWithPriority(String name, EntryType type) throws BlockException { public static Entry entryWithPriority(String name, EntryType type) throws BlockException {
return Env.sph.entryWithPriority(name, type, 1, true); 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);
}
} }

View File

@ -40,6 +40,12 @@ public @interface SentinelResource {
*/ */
EntryType entryType() default EntryType.OUT; 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 * @return name of the block exception function, empty by default
*/ */

View File

@ -19,8 +19,10 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import com.alibaba.csp.sentinel.ResourceTypeConstants;
import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.util.AssertUtil;
/** /**
* <p> * <p>
@ -42,6 +44,19 @@ import com.alibaba.csp.sentinel.slots.block.BlockException;
*/ */
public class ClusterNode extends StatisticNode { 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>The origin map holds the pair: (origin, originNode) for one specific resource.</p>
* <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. * at the very beginning while concurrent map will hold the lock all the time.
* </p> * </p>
*/ */
private Map<String, StatisticNode> originCountMap = new HashMap<String, StatisticNode>(); private Map<String, StatisticNode> originCountMap = new HashMap<>();
private final ReentrantLock lock = new ReentrantLock(); 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>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} * <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; return statisticNode;
} }
public synchronized Map<String, StatisticNode> getOriginCountMap() { public Map<String, StatisticNode> getOriginCountMap() {
return originCountMap; return originCountMap;
} }

View File

@ -27,6 +27,13 @@ import java.util.Date;
*/ */
public class MetricNode { 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 timestamp;
private long passQps; private long passQps;
private long blockQps; private long blockQps;
@ -38,8 +45,10 @@ public class MetricNode {
* @since 1.5.0 * @since 1.5.0
*/ */
private long occupiedPassQps; private long occupiedPassQps;
/**
private String resource; * @since 1.7.0
*/
private int concurrency;
public long getTimestamp() { public long getTimestamp() {
return timestamp; return timestamp;
@ -105,12 +114,38 @@ public class MetricNode {
this.resource = resource; 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 @Override
public String toString() { public String toString() {
return "MetricNode{" + "timestamp=" + timestamp + ", passQps=" + passQps + ", blockQps=" + blockQps return "MetricNode{" +
+ ", successQps=" + successQps + ", exceptionQps=" + exceptionQps + ", rt=" + rt "resource='" + resource + '\'' +
+ ", occupiedPassQps=" + occupiedPassQps + ", resource='" ", classification=" + classification +
+ resource + '\'' + '}'; ", 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(successQps).append("|");
sb.append(exceptionQps).append("|"); sb.append(exceptionQps).append("|");
sb.append(rt).append("|"); sb.append(rt).append("|");
sb.append(occupiedPassQps); sb.append(occupiedPassQps).append("|");
sb.append(concurrency).append("|");
sb.append(classification);
return sb.toString(); return sb.toString();
} }
@ -152,9 +189,15 @@ public class MetricNode {
node.setSuccessQps(Long.parseLong(strs[4])); node.setSuccessQps(Long.parseLong(strs[4]));
node.setExceptionQps(Long.parseLong(strs[5])); node.setExceptionQps(Long.parseLong(strs[5]));
node.setRt(Long.parseLong(strs[6])); node.setRt(Long.parseLong(strs[6]));
if (strs.length == 8) { if (strs.length >= 8) {
node.setOccupiedPassQps(Long.parseLong(strs[7])); 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; return node;
} }
@ -180,7 +223,9 @@ public class MetricNode {
sb.append(getSuccessQps()).append("|"); sb.append(getSuccessQps()).append("|");
sb.append(getExceptionQps()).append("|"); sb.append(getExceptionQps()).append("|");
sb.append(getRt()).append("|"); sb.append(getRt()).append("|");
sb.append(getOccupiedPassQps()); sb.append(getOccupiedPassQps()).append("|");
sb.append(concurrency).append("|");
sb.append(classification);
sb.append('\n'); sb.append('\n');
return sb.toString(); return sb.toString();
} }
@ -202,9 +247,15 @@ public class MetricNode {
node.setSuccessQps(Long.parseLong(strs[5])); node.setSuccessQps(Long.parseLong(strs[5]));
node.setExceptionQps(Long.parseLong(strs[6])); node.setExceptionQps(Long.parseLong(strs[6]));
node.setRt(Long.parseLong(strs[7])); node.setRt(Long.parseLong(strs[7]));
if (strs.length == 9) { if (strs.length >= 9) {
node.setOccupiedPassQps(Long.parseLong(strs[8])); 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; return node;
} }

View File

@ -38,14 +38,13 @@ public class MetricTimerListener implements Runnable {
@Override @Override
public void run() { 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()) { for (Entry<ResourceWrapper, ClusterNode> e : ClusterBuilderSlot.getClusterNodeMap().entrySet()) {
String name = e.getKey().getName();
ClusterNode node = e.getValue(); ClusterNode node = e.getValue();
Map<Long, MetricNode> metrics = node.metrics(); 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()) { if (!maps.isEmpty()) {
for (Entry<Long, List<MetricNode>> entry : maps.entrySet()) { for (Entry<Long, List<MetricNode>> entry : maps.entrySet()) {
try { 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()) { for (Entry<Long, MetricNode> entry : metrics.entrySet()) {
long time = entry.getKey(); long time = entry.getKey();
MetricNode metricNode = entry.getValue(); MetricNode metricNode = entry.getValue();
metricNode.setResource(resourceName); metricNode.setResource(node.getName());
metricNode.setClassification(node.getResourceType());
if (maps.get(time) == null) { if (maps.get(time) == null) {
maps.put(time, new ArrayList<MetricNode>()); maps.put(time, new ArrayList<MetricNode>());
} }

View File

@ -18,6 +18,7 @@ package com.alibaba.csp.sentinel.slotchain;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import com.alibaba.csp.sentinel.EntryType; 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.IdUtil;
import com.alibaba.csp.sentinel.util.MethodUtil; import com.alibaba.csp.sentinel.util.MethodUtil;
@ -28,17 +29,15 @@ import com.alibaba.csp.sentinel.util.MethodUtil;
*/ */
public class MethodResourceWrapper extends ResourceWrapper { public class MethodResourceWrapper extends ResourceWrapper {
private transient Method method; private final transient Method method;
public MethodResourceWrapper(Method method, EntryType type) { public MethodResourceWrapper(Method method, EntryType e) {
this.method = method; this(method, e, ResourceTypeConstants.COMMON);
this.name = MethodUtil.resolveMethodName(method);
this.type = type;
} }
@Override public MethodResourceWrapper(Method method, EntryType e, int resType) {
public String getName() { super(MethodUtil.resolveMethodName(method), e, resType);
return name; this.method = method;
} }
public Method getMethod() { public Method getMethod() {
@ -51,8 +50,11 @@ public class MethodResourceWrapper extends ResourceWrapper {
} }
@Override @Override
public EntryType getType() { public String toString() {
return type; return "MethodResourceWrapper{" +
"name='" + name + '\'' +
", entryType=" + entryType +
", resourceType=" + resourceType +
'}';
} }
} }

View File

@ -16,28 +16,64 @@
package com.alibaba.csp.sentinel.slotchain; package com.alibaba.csp.sentinel.slotchain;
import com.alibaba.csp.sentinel.EntryType; 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 qinan.qn
* @author jialiang.linjl * @author jialiang.linjl
* @author Eric Zhao
*/ */
public abstract class ResourceWrapper { public abstract class ResourceWrapper {
protected String name; protected final String name;
protected EntryType type = EntryType.OUT;
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. * Get {@link EntryType} of this wrapper.
* *
* @return {@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. * Only {@link #getName()} is considered.

View File

@ -16,26 +16,22 @@
package com.alibaba.csp.sentinel.slotchain; package com.alibaba.csp.sentinel.slotchain;
import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.ResourceTypeConstants;
/** /**
* Common resource wrapper. * Common string resource wrapper.
* *
* @author qinan.qn * @author qinan.qn
* @author jialiang.linjl * @author jialiang.linjl
*/ */
public class StringResourceWrapper extends ResourceWrapper { public class StringResourceWrapper extends ResourceWrapper {
public StringResourceWrapper(String name, EntryType type) { public StringResourceWrapper(String name, EntryType e) {
if (name == null) { super(name, e, ResourceTypeConstants.COMMON);
throw new IllegalArgumentException("Resource name cannot be null");
}
this.name = name;
this.type = type;
} }
@Override public StringResourceWrapper(String name, EntryType e, int resType) {
public String getName() { super(name, e, resType);
return name;
} }
@Override @Override
@ -43,16 +39,12 @@ public class StringResourceWrapper extends ResourceWrapper {
return name; return name;
} }
@Override
public EntryType getType() {
return type;
}
@Override @Override
public String toString() { public String toString() {
return "StringResourceWrapper{" + return "StringResourceWrapper{" +
"name='" + name + '\'' + "name='" + name + '\'' +
", type=" + type + ", entryType=" + entryType +
", resourceType=" + resourceType +
'}'; '}';
} }
} }

View File

@ -78,7 +78,7 @@ public class ClusterBuilderSlot extends AbstractLinkedProcessorSlot<DefaultNode>
synchronized (lock) { synchronized (lock) {
if (clusterNode == null) { if (clusterNode == null) {
// Create the cluster node. // 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)); HashMap<ResourceWrapper, ClusterNode> newMap = new HashMap<>(Math.max(clusterNodeMap.size(), 16));
newMap.putAll(clusterNodeMap); newMap.putAll(clusterNodeMap);
newMap.put(node.getId(), clusterNode); newMap.put(node.getId(), clusterNode);

View File

@ -65,7 +65,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
context.getCurEntry().getOriginNode().addPassRequest(count); 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. // Add count for global inbound entry node for global statistics.
Constants.ENTRY_NODE.increaseThreadNum(); Constants.ENTRY_NODE.increaseThreadNum();
Constants.ENTRY_NODE.addPassRequest(count); Constants.ENTRY_NODE.addPassRequest(count);
@ -82,7 +82,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
context.getCurEntry().getOriginNode().increaseThreadNum(); context.getCurEntry().getOriginNode().increaseThreadNum();
} }
if (resourceWrapper.getType() == EntryType.IN) { if (resourceWrapper.getEntryType() == EntryType.IN) {
// Add count for global inbound entry node for global statistics. // Add count for global inbound entry node for global statistics.
Constants.ENTRY_NODE.increaseThreadNum(); Constants.ENTRY_NODE.increaseThreadNum();
} }
@ -100,7 +100,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
context.getCurEntry().getOriginNode().increaseBlockQps(count); 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. // Add count for global inbound entry node for global statistics.
Constants.ENTRY_NODE.increaseBlockQps(count); Constants.ENTRY_NODE.increaseBlockQps(count);
} }
@ -121,7 +121,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
context.getCurEntry().getOriginNode().increaseExceptionQps(count); context.getCurEntry().getOriginNode().increaseExceptionQps(count);
} }
if (resourceWrapper.getType() == EntryType.IN) { if (resourceWrapper.getEntryType() == EntryType.IN) {
Constants.ENTRY_NODE.increaseExceptionQps(count); Constants.ENTRY_NODE.increaseExceptionQps(count);
} }
throw e; throw e;
@ -151,7 +151,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
context.getCurEntry().getOriginNode().decreaseThreadNum(); context.getCurEntry().getOriginNode().decreaseThreadNum();
} }
if (resourceWrapper.getType() == EntryType.IN) { if (resourceWrapper.getEntryType() == EntryType.IN) {
Constants.ENTRY_NODE.addRtAndSuccess(rt, count); Constants.ENTRY_NODE.addRtAndSuccess(rt, count);
Constants.ENTRY_NODE.decreaseThreadNum(); Constants.ENTRY_NODE.decreaseThreadNum();
} }

View File

@ -297,7 +297,7 @@ public final class SystemRuleManager {
} }
// for inbound traffic only // for inbound traffic only
if (resourceWrapper.getType() != EntryType.IN) { if (resourceWrapper.getEntryType() != EntryType.IN) {
return; return;
} }

View File

@ -41,7 +41,7 @@ public class CtSphTest {
Entry entry = null; Entry entry = null;
try { try {
if (async) { if (async) {
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getType(), 1); entry = ctSph.asyncEntry(resourceName, resourceWrapper.getEntryType(), 1);
} else { } else {
entry = ctSph.entry(resourceWrapper, 1); entry = ctSph.entry(resourceWrapper, 1);
} }
@ -80,7 +80,7 @@ public class CtSphTest {
if (!async) { if (!async) {
entry = ctSph.entry(resourceWrapper, 1); entry = ctSph.entry(resourceWrapper, 1);
} else { } else {
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getType(), 1); entry = ctSph.asyncEntry(resourceName, resourceWrapper.getEntryType(), 1);
Context asyncContext = ((AsyncEntry)entry).getAsyncContext(); Context asyncContext = ((AsyncEntry)entry).getAsyncContext();
assertTrue(ContextUtil.isDefaultContext(asyncContext)); assertTrue(ContextUtil.isDefaultContext(asyncContext));
assertTrue(asyncContext.isAsync()); assertTrue(asyncContext.isAsync());
@ -127,7 +127,7 @@ public class CtSphTest {
AsyncEntry asyncEntry = null; AsyncEntry asyncEntry = null;
try { try {
entry = ctSph.entry(resourceWrapperA, 1); entry = ctSph.entry(resourceWrapperA, 1);
asyncEntry = ctSph.asyncEntry(resourceNameB, resourceWrapperB.getType(), 1); asyncEntry = ctSph.asyncEntry(resourceNameB, resourceWrapperB.getEntryType(), 1);
} catch (BlockException ex) { } catch (BlockException ex) {
fail("Unexpected blocked: " + ex.getClass().getCanonicalName()); fail("Unexpected blocked: " + ex.getClass().getCanonicalName());
} finally { } finally {

View File

@ -63,7 +63,7 @@ public class SphOTest {
try { try {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.OUT); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.OUT);
} finally { } finally {
SphO.exit(2); SphO.exit(2);
} }
@ -78,7 +78,7 @@ public class SphOTest {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(),
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryCount()")); "com.alibaba.csp.sentinel.SphOTest:testMethodEntryCount()"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.OUT); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.OUT);
} finally { } finally {
SphO.exit(2); SphO.exit(2);
} }
@ -91,7 +91,7 @@ public class SphOTest {
try { try {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN);
} finally { } finally {
SphO.exit(); SphO.exit();
} }
@ -106,7 +106,7 @@ public class SphOTest {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(),
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryType()")); "com.alibaba.csp.sentinel.SphOTest:testMethodEntryType()"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN);
} finally { } finally {
SphO.exit(); SphO.exit();
} }
@ -119,7 +119,7 @@ public class SphOTest {
try { try {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN);
} finally { } finally {
SphO.exit(2); SphO.exit(2);
} }
@ -134,7 +134,7 @@ public class SphOTest {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(),
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryTypeCount()")); "com.alibaba.csp.sentinel.SphOTest:testMethodEntryTypeCount()"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN);
} finally { } finally {
SphO.exit(2); SphO.exit(2);
} }
@ -147,7 +147,7 @@ public class SphOTest {
try { try {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName")); ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), "resourceName"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN);
} finally { } finally {
SphO.exit(2, "hello1", "hello2"); SphO.exit(2, "hello1", "hello2");
} }
@ -162,7 +162,7 @@ public class SphOTest {
assertTrue(StringUtil.equalsIgnoreCase( assertTrue(StringUtil.equalsIgnoreCase(
ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(), ContextUtil.getContext().getCurEntry().getResourceWrapper().getName(),
"com.alibaba.csp.sentinel.SphOTest:testMethodEntryAll()")); "com.alibaba.csp.sentinel.SphOTest:testMethodEntryAll()"));
assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getType(), EntryType.IN); assertSame(ContextUtil.getContext().getCurEntry().getResourceWrapper().getEntryType(), EntryType.IN);
} finally { } finally {
SphO.exit(2, "hello1", "hello2"); SphO.exit(2, "hello1", "hello2");
} }

View File

@ -38,7 +38,7 @@ public class SphUTest {
assertNotNull(e); assertNotNull(e);
assertEquals(e.resourceWrapper.getName(), "resourceName"); 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); assertEquals(ContextUtil.getContext().getName(), Constants.CONTEXT_DEFAULT_NAME);
e.exit(); e.exit();
@ -53,7 +53,7 @@ public class SphUTest {
assertTrue(StringUtil assertTrue(StringUtil
.equalsIgnoreCase(e.resourceWrapper.getName(), .equalsIgnoreCase(e.resourceWrapper.getName(),
"com.alibaba.csp.sentinel.SphUTest:testMethodEntryNormal()")); "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); assertEquals(ContextUtil.getContext().getName(), Constants.CONTEXT_DEFAULT_NAME);
e.exit(); e.exit();
@ -78,7 +78,7 @@ public class SphUTest {
assertNotNull(e); assertNotNull(e);
assertEquals("resourceName", e.resourceWrapper.getName()); 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); assertEquals(ContextUtil.getContext().getName(), Constants.CONTEXT_DEFAULT_NAME);
e.exit(2); e.exit(2);
@ -93,7 +93,7 @@ public class SphUTest {
assertTrue(StringUtil assertTrue(StringUtil
.equalsIgnoreCase(e.resourceWrapper.getName(), .equalsIgnoreCase(e.resourceWrapper.getName(),
"com.alibaba.csp.sentinel.SphUTest:testMethodEntryNormal()")); "com.alibaba.csp.sentinel.SphUTest:testMethodEntryNormal()"));
assertEquals(e.resourceWrapper.getType(), EntryType.OUT); assertEquals(e.resourceWrapper.getEntryType(), EntryType.OUT);
e.exit(2); e.exit(2);
} }
@ -102,7 +102,7 @@ public class SphUTest {
public void testStringEntryType() throws BlockException { public void testStringEntryType() throws BlockException {
Entry e = SphU.entry("resourceName", EntryType.IN); Entry e = SphU.entry("resourceName", EntryType.IN);
assertSame(e.resourceWrapper.getType(), EntryType.IN); assertSame(e.resourceWrapper.getEntryType(), EntryType.IN);
e.exit(); e.exit();
} }
@ -112,7 +112,7 @@ public class SphUTest {
Method method = SphUTest.class.getMethod("testMethodEntryNormal"); Method method = SphUTest.class.getMethod("testMethodEntryNormal");
Entry e = SphU.entry(method, EntryType.IN); Entry e = SphU.entry(method, EntryType.IN);
assertSame(e.resourceWrapper.getType(), EntryType.IN); assertSame(e.resourceWrapper.getEntryType(), EntryType.IN);
e.exit(); e.exit();
} }
@ -121,7 +121,7 @@ public class SphUTest {
public void testStringEntryCountType() throws BlockException { public void testStringEntryCountType() throws BlockException {
Entry e = SphU.entry("resourceName", EntryType.IN, 2); Entry e = SphU.entry("resourceName", EntryType.IN, 2);
assertSame(e.resourceWrapper.getType(), EntryType.IN); assertSame(e.resourceWrapper.getEntryType(), EntryType.IN);
e.exit(2); e.exit(2);
} }
@ -131,7 +131,7 @@ public class SphUTest {
Method method = SphUTest.class.getMethod("testMethodEntryNormal"); Method method = SphUTest.class.getMethod("testMethodEntryNormal");
Entry e = SphU.entry(method, EntryType.IN, 2); Entry e = SphU.entry(method, EntryType.IN, 2);
assertSame(e.resourceWrapper.getType(), EntryType.IN); assertSame(e.resourceWrapper.getEntryType(), EntryType.IN);
e.exit(); e.exit();
} }
@ -141,7 +141,7 @@ public class SphUTest {
final String arg0 = "foo"; final String arg0 = "foo";
final String arg1 = "baz"; final String arg1 = "baz";
Entry e = SphU.entry("resourceName", EntryType.IN, 2, arg0, arg1); 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); e.exit(2, arg0, arg1);
} }
@ -153,7 +153,7 @@ public class SphUTest {
Method method = SphUTest.class.getMethod("testMethodEntryNormal"); Method method = SphUTest.class.getMethod("testMethodEntryNormal");
Entry e = SphU.entry(method, EntryType.IN, 2, arg0, arg1); 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); e.exit(2, arg0, arg1);
} }

View File

@ -41,7 +41,7 @@ public class ClusterNodeTest {
@Test @Test
public void testGetOrCreateOriginNodeSingleThread() { public void testGetOrCreateOriginNodeSingleThread() {
ClusterNode clusterNode = new ClusterNode(); ClusterNode clusterNode = new ClusterNode("test");
String origin1 = "origin1"; String origin1 = "origin1";
Node originNode1 = clusterNode.getOrCreateOriginNode(origin1); Node originNode1 = clusterNode.getOrCreateOriginNode(origin1);
@ -74,7 +74,7 @@ public class ClusterNodeTest {
final int testTimes = 10; final int testTimes = 10;
for (int times = 0; times < testTimes; times++) { 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. // Store all distinct nodes by calling ClusterNode#getOrCreateOriginNode.
// Here we need a thread-safe concurrent set (created from ConcurrentHashMap). // Here we need a thread-safe concurrent set (created from ConcurrentHashMap).
@ -130,7 +130,7 @@ public class ClusterNodeTest {
@Test @Test
public void testTraceException() { public void testTraceException() {
ClusterNode clusterNode = new ClusterNode(); ClusterNode clusterNode = new ClusterNode("test");
Exception exception = new RuntimeException("test"); Exception exception = new RuntimeException("test");

View File

@ -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());
}
}