Support classification for Sentinel resources
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
9d514d5036
commit
6bb2de8750
|
|
@ -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.
|
||||
*
|
||||
|
|
@ -267,4 +269,87 @@ public class SphU {
|
|||
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());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue