diff --git a/pom.xml b/pom.xml index cd36ec726c..24f73600cb 100755 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ 1.2.83_noneautotype 1.3.2 + 2.9.3 4.12 @@ -219,6 +220,11 @@ ${powermock.version} test + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNode.java b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNode.java index be734ad306..3bf7fbd3e5 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNode.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNode.java @@ -21,7 +21,7 @@ /** * We use TokenCacheNodeManager to store the tokenId, whose the underlying storage structure - * is ConcurrentLinkedHashMap, Its storage node is TokenCacheNode. In order to operate the nowCalls value when + * is Caffeine, Its storage node is TokenCacheNode. In order to operate the nowCalls value when * the expired tokenId is deleted regularly, we need to store the flowId in TokenCacheNode. * * @author yunfeiyanggzq diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManager.java b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManager.java index 890f62e6da..2fe3ef5c16 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManager.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManager.java @@ -16,9 +16,9 @@ package com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent; import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.expire.RegularExpireStrategy; +import com.alibaba.csp.sentinel.slots.statistic.cache.CacheMap; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import com.alibaba.csp.sentinel.util.AssertUtil; -import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; -import com.googlecode.concurrentlinkedhashmap.Weighers; import java.util.Set; @@ -26,7 +26,7 @@ * @author yunfeiyanggzq */ public class TokenCacheNodeManager { - private static ConcurrentLinkedHashMap TOKEN_CACHE_NODE_MAP; + private static CacheMap TOKEN_CACHE_NODE_MAP; private static final int DEFAULT_CONCURRENCY_LEVEL = 16; @@ -40,11 +40,7 @@ public static void prepare(int concurrencyLevel, int maximumWeightedCapacity) { AssertUtil.isTrue(concurrencyLevel > 0, "concurrencyLevel must be positive"); AssertUtil.isTrue(maximumWeightedCapacity > 0, "maximumWeightedCapacity must be positive"); - TOKEN_CACHE_NODE_MAP = new ConcurrentLinkedHashMap.Builder() - .concurrencyLevel(concurrencyLevel) - .maximumWeightedCapacity(maximumWeightedCapacity) - .weigher(Weighers.singleton()) - .build(); + TOKEN_CACHE_NODE_MAP = new CaffeineCacheMapWrapper<>(maximumWeightedCapacity); // Start the task of regularly clearing expired keys RegularExpireStrategy strategy = new RegularExpireStrategy(TOKEN_CACHE_NODE_MAP); strategy.startClearTaskRegularly(); @@ -52,8 +48,7 @@ public static void prepare(int concurrencyLevel, int maximumWeightedCapacity) { public static TokenCacheNode getTokenCacheNode(long tokenId) { - //use getQuietly to prevent disorder - return TOKEN_CACHE_NODE_MAP.getQuietly(tokenId); + return TOKEN_CACHE_NODE_MAP.get(tokenId); } public static void putTokenCacheNode(long tokenId, TokenCacheNode cacheNode) { @@ -69,7 +64,7 @@ public static TokenCacheNode removeTokenCacheNode(long tokenId) { } public static int getSize() { - return TOKEN_CACHE_NODE_MAP.size(); + return (int) TOKEN_CACHE_NODE_MAP.size(); } public static Set getCacheKeySet() { diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/expire/RegularExpireStrategy.java b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/expire/RegularExpireStrategy.java index 24fd42fbfc..6e388fd7d2 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/expire/RegularExpireStrategy.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/expire/RegularExpireStrategy.java @@ -21,8 +21,8 @@ import com.alibaba.csp.sentinel.cluster.server.connection.ConnectionManager; import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; import com.alibaba.csp.sentinel.log.RecordLog; +import com.alibaba.csp.sentinel.slots.statistic.cache.CacheMap; import com.alibaba.csp.sentinel.util.AssertUtil; -import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import java.util.ArrayList; import java.util.List; @@ -62,14 +62,14 @@ public class RegularExpireStrategy implements ExpireStrategy { /** * the local cache of tokenId */ - private ConcurrentLinkedHashMap localCache; + private CacheMap localCache; @SuppressWarnings("PMD.ThreadPoolCreationRule") private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("regular clear expired token thread", true)); - public RegularExpireStrategy(ConcurrentLinkedHashMap localCache) { + public RegularExpireStrategy(CacheMap localCache) { AssertUtil.isTrue(localCache != null, " local cache can't be null"); this.localCache = localCache; } diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParameterLeapArray.java b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParameterLeapArray.java index 2b5fabc4e7..b71b737b80 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParameterLeapArray.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParameterLeapArray.java @@ -18,7 +18,7 @@ import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray; import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; import com.alibaba.csp.sentinel.slots.statistic.cache.CacheMap; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import com.alibaba.csp.sentinel.util.AssertUtil; /** @@ -38,7 +38,7 @@ public ClusterParameterLeapArray(int sampleCount, int intervalInMs, int maxCapac @Override public CacheMap newEmptyBucket(long timeMillis) { - return new ConcurrentLinkedHashMapWrapper<>(maxCapacity); + return new CaffeineCacheMapWrapper<>(maxCapacity); } @Override diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java index 8ca4f97a40..c06fd6b946 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java @@ -16,8 +16,6 @@ package com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent; import com.alibaba.csp.sentinel.cluster.flow.rule.ClusterFlowRuleManager; -import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode; -import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNodeManager; import com.alibaba.csp.sentinel.slots.block.ClusterRuleConstant; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig; diff --git a/sentinel-extension/sentinel-parameter-flow-control/pom.xml b/sentinel-extension/sentinel-parameter-flow-control/pom.xml index 43a349d2ae..72df4dd210 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/pom.xml +++ b/sentinel-extension/sentinel-parameter-flow-control/pom.xml @@ -24,9 +24,8 @@ - com.googlecode.concurrentlinkedhashmap - concurrentlinkedhashmap-lru - 1.4.2 + com.github.ben-manes.caffeine + caffeine diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParameterMetric.java b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParameterMetric.java index ee29728a37..1ba5372720 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParameterMetric.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParameterMetric.java @@ -24,7 +24,7 @@ import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.slots.statistic.cache.CacheMap; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; /** * Metrics for frequent ("hot spot") parameters. @@ -97,7 +97,7 @@ public void initialize(ParamFlowRule rule) { synchronized (lock) { if (ruleTimeCounters.get(rule) == null) { long size = Math.min(BASE_PARAM_MAX_CAPACITY * rule.getDurationInSec(), TOTAL_MAX_CAPACITY); - ruleTimeCounters.put(rule, new ConcurrentLinkedHashMapWrapper(size)); + ruleTimeCounters.put(rule, new CaffeineCacheMapWrapper<>(size)); } } } @@ -106,7 +106,7 @@ public void initialize(ParamFlowRule rule) { synchronized (lock) { if (ruleTokenCounter.get(rule) == null) { long size = Math.min(BASE_PARAM_MAX_CAPACITY * rule.getDurationInSec(), TOTAL_MAX_CAPACITY); - ruleTokenCounter.put(rule, new ConcurrentLinkedHashMapWrapper(size)); + ruleTokenCounter.put(rule, new CaffeineCacheMapWrapper<>(size)); } } } @@ -115,7 +115,7 @@ public void initialize(ParamFlowRule rule) { synchronized (lock) { if (threadCountMap.get(rule.getParamIdx()) == null) { threadCountMap.put(rule.getParamIdx(), - new ConcurrentLinkedHashMapWrapper(THREAD_COUNT_MAX_CAPACITY)); + new CaffeineCacheMapWrapper<>(THREAD_COUNT_MAX_CAPACITY)); } } } diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CacheMap.java b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CacheMap.java index 4039632b7d..6d0aa76a9d 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CacheMap.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CacheMap.java @@ -42,4 +42,8 @@ public interface CacheMap { void clear(); Set keySet(boolean ascending); + + default Set keySet() { + return keySet(true); + } } diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/ConcurrentLinkedHashMapWrapper.java b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CaffeineCacheMapWrapper.java similarity index 52% rename from sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/ConcurrentLinkedHashMapWrapper.java rename to sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CaffeineCacheMapWrapper.java index 8b25e0c04c..2dd19e4dd5 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/ConcurrentLinkedHashMapWrapper.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/cache/CaffeineCacheMapWrapper.java @@ -15,35 +15,36 @@ */ package com.alibaba.csp.sentinel.slots.statistic.cache; -import java.util.Set; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; -import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; -import com.googlecode.concurrentlinkedhashmap.Weighers; +import java.util.Comparator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; /** - * A {@link ConcurrentLinkedHashMap} wrapper for the universal {@link CacheMap}. + * A {@link Cache} wrapper for the universal {@link CacheMap}. + * + * @author shaoqiangyan * - * @author Eric Zhao - * @since 0.2.0 */ -public class ConcurrentLinkedHashMapWrapper implements CacheMap { +public class CaffeineCacheMapWrapper implements CacheMap { - private static final int DEFAULT_CONCURRENCY_LEVEL = 16; - private final ConcurrentLinkedHashMap map; + private final Cache map; - public ConcurrentLinkedHashMapWrapper(long size) { + public CaffeineCacheMapWrapper(long size) { if (size <= 0) { throw new IllegalArgumentException("Cache max capacity should be positive: " + size); } - this.map = new ConcurrentLinkedHashMap.Builder() - .concurrencyLevel(DEFAULT_CONCURRENCY_LEVEL) - .maximumWeightedCapacity(size) - .weigher(Weighers.singleton()) - .build(); + this.map = Caffeine.newBuilder() + .maximumSize(size) + .build(); } - public ConcurrentLinkedHashMapWrapper(ConcurrentLinkedHashMap map) { + public CaffeineCacheMapWrapper(Cache map) { if (map == null) { throw new IllegalArgumentException("Invalid map instance"); } @@ -52,45 +53,52 @@ public ConcurrentLinkedHashMapWrapper(ConcurrentLinkedHashMap map) { @Override public boolean containsKey(T key) { - return map.containsKey(key); + return asMap().containsKey(key); } @Override public R get(T key) { - return map.get(key); + return map.getIfPresent(key); } @Override public R remove(T key) { - return map.remove(key); + return asMap().remove(key); } @Override public R put(T key, R value) { - return map.put(key, value); + return asMap().put(key, value); } @Override public R putIfAbsent(T key, R value) { - return map.putIfAbsent(key, value); + return asMap().putIfAbsent(key, value); } @Override public long size() { - return map.weightedSize(); + return asMap().size(); } @Override public void clear() { - map.clear(); + map.invalidateAll(); } @Override + @SuppressWarnings("unchecked") public Set keySet(boolean ascending) { + Comparator comparator; if (ascending) { - return map.ascendingKeySet(); + comparator = (Comparator) Comparator.naturalOrder(); } else { - return map.descendingKeySet(); + comparator = (Comparator) Comparator.reverseOrder(); } + return asMap().keySet().stream().sorted(comparator).collect(Collectors.toCollection(LinkedHashSet::new)); + } + + private ConcurrentMap asMap() { + return map.asMap(); } } diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucket.java b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucket.java index 24e1d1d055..3064218c9d 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucket.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucket.java @@ -20,7 +20,7 @@ import com.alibaba.csp.sentinel.slots.block.flow.param.RollingParamEvent; import com.alibaba.csp.sentinel.slots.statistic.cache.CacheMap; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import com.alibaba.csp.sentinel.util.AssertUtil; /** @@ -43,7 +43,7 @@ public ParamMapBucket(int capacity) { RollingParamEvent[] events = RollingParamEvent.values(); this.data = new CacheMap[events.length]; for (RollingParamEvent event : events) { - data[event.ordinal()] = new ConcurrentLinkedHashMapWrapper(capacity); + data[event.ordinal()] = new CaffeineCacheMapWrapper<>(capacity); } } diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowCheckerTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowCheckerTest.java index bc545c6f84..72a8bd64ad 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowCheckerTest.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowCheckerTest.java @@ -19,7 +19,7 @@ import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; import com.alibaba.csp.sentinel.slots.block.RuleConstant; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.After; import org.junit.Before; @@ -30,7 +30,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -89,7 +88,7 @@ public void testSingleValueCheckQpsWithExceptionItems() throws InterruptedExcept ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueB)); @@ -157,8 +156,8 @@ public void testPassLocalCheckForCollection() throws InterruptedException { List list = Arrays.asList(v1, v2, v3); ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); + metric.getRuleTokenCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); assertTrue(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, list)); assertFalse(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, list)); @@ -180,7 +179,7 @@ public void testPassLocalCheckForArray() throws InterruptedException { Object arr = new String[]{v1, v2, v3}; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); assertTrue(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, arr)); assertFalse(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, arr)); @@ -214,8 +213,8 @@ public Object paramFlowKey() { Object[] args = new Object[]{new User(1, "Bob", "Hangzhou"), 10, "Demo"}; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); + metric.getRuleTokenCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); assertTrue(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, args)); assertFalse(ParamFlowChecker.passCheck(resourceWrapper, rule, 1, args)); diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java index 581c8522fd..bdd0b94ece 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java @@ -23,7 +23,6 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; import org.junit.After; import org.junit.Before; @@ -32,7 +31,7 @@ import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; import com.alibaba.csp.sentinel.util.TimeUtil; @@ -59,9 +58,9 @@ public void testCheckQpsWithLongIntervalAndHighThreshold() { String valueA = "valueA"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); + new CaffeineCacheMapWrapper<>(4000)); // We mock the time directly to avoid unstable behaviour. setCurrentMillis(System.currentTimeMillis()); @@ -97,9 +96,9 @@ public void testParamFlowDefaultCheckSingleQps() { String valueA = "valueA"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); + new CaffeineCacheMapWrapper<>(4000)); // We mock the time directly to avoid unstable behaviour. setCurrentMillis(System.currentTimeMillis()); @@ -137,9 +136,9 @@ public void testParamFlowDefaultCheckSingleQpsWithBurst() throws InterruptedExce String valueA = "valueA"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); + new CaffeineCacheMapWrapper<>(4000)); // We mock the time directly to avoid unstable behaviour. setCurrentMillis(System.currentTimeMillis()); @@ -207,9 +206,9 @@ public void testParamFlowDefaultCheckQpsInDifferentDuration() throws Interrupted String valueA = "helloWorld"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); + new CaffeineCacheMapWrapper<>(4000)); // We mock the time directly to avoid unstable behaviour. setCurrentMillis(System.currentTimeMillis()); @@ -260,9 +259,9 @@ public void testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads() throws final String valueA = "valueA"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper<>(4000)); metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); + new CaffeineCacheMapWrapper<>(4000)); int threadCount = 40; final CountDownLatch waitLatch = new CountDownLatch(threadCount); diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlotTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlotTest.java index aadef74abd..91e00448b7 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlotTest.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlotTest.java @@ -16,17 +16,15 @@ package com.alibaba.csp.sentinel.slots.block.flow.param; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Collections; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -35,7 +33,6 @@ import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; import com.alibaba.csp.sentinel.slots.statistic.cache.CacheMap; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; import com.alibaba.csp.sentinel.util.TimeUtil; /** @@ -99,8 +96,8 @@ public void testEntryWhenParamFlowExists() throws Throwable { ParameterMetric metric = mock(ParameterMetric.class); - CacheMap map = new ConcurrentLinkedHashMapWrapper<>(4000); - CacheMap map2 = new ConcurrentLinkedHashMapWrapper<>(4000); + CacheMap map = new CaffeineCacheMapWrapper<>(4000); + CacheMap map2 = new CaffeineCacheMapWrapper<>(4000); when(metric.getRuleTimeCounter(rule)).thenReturn(map); when(metric.getRuleTokenCounter(rule)).thenReturn(map2); map.put(argToGo, new AtomicLong(TimeUtil.currentTimeMillis())); diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowThrottleRateLimitingCheckerTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowThrottleRateLimitingCheckerTest.java index 8d9cfde48a..02454503ba 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowThrottleRateLimitingCheckerTest.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowThrottleRateLimitingCheckerTest.java @@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import com.alibaba.csp.sentinel.slots.statistic.cache.CaffeineCacheMapWrapper; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -29,7 +30,6 @@ import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; import com.alibaba.csp.sentinel.slots.block.RuleConstant; -import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; import com.alibaba.csp.sentinel.util.TimeUtil; import static org.junit.Assert.assertEquals; @@ -57,7 +57,7 @@ public void testSingleValueThrottleCheckQps() throws Exception { String valueA = "valueA"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper(4000)); long currentTime = TimeUtil.currentTimeMillis(); long endTime = currentTime + rule.getDurationInSec() * 1000; @@ -101,7 +101,7 @@ public void testSingleValueThrottleCheckQpsMultipleThreads() throws Exception { final String valueA = "valueA"; ParameterMetric metric = new ParameterMetric(); ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTimeCounterMap().put(rule, new CaffeineCacheMapWrapper(4000)); int threadCount = 40; System.out.println(metric.getRuleTimeCounter(rule)); diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucketTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucketTest.java index 5935b81982..075ccddc2f 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucketTest.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/statistic/data/ParamMapBucketTest.java @@ -19,6 +19,11 @@ import org.junit.Test; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import static org.junit.Assert.*; /** @@ -30,13 +35,14 @@ public class ParamMapBucketTest { @Test - public void testAddEviction() { + public void testAddEviction() throws InterruptedException { ParamMapBucket bucket = new ParamMapBucket(); for (int i = 0; i < ParamMapBucket.DEFAULT_MAX_CAPACITY; i++) { bucket.add(RollingParamEvent.REQUEST_PASSED, 1, "param-" + i); } String lastParam = "param-end"; bucket.add(RollingParamEvent.REQUEST_PASSED, 1, lastParam); + TimeUnit.MILLISECONDS.sleep(10L); assertEquals(0, bucket.get(RollingParamEvent.REQUEST_PASSED, "param-0")); assertEquals(1, bucket.get(RollingParamEvent.REQUEST_PASSED, "param-1")); assertEquals(1, bucket.get(RollingParamEvent.REQUEST_PASSED, lastParam)); @@ -74,4 +80,27 @@ public void testAddGetResetCommon() { assertEquals(0, bucket.get(RollingParamEvent.REQUEST_PASSED, paramB)); assertEquals(0, bucket.get(RollingParamEvent.REQUEST_PASSED, paramC)); } + + @Test + public void testOrder() { + ParamMapBucket bucket = new ParamMapBucket(); + double paramA = 1.1d; + double paramB = 2.2d; + double paramC = -3.2d; + bucket.add(RollingParamEvent.REQUEST_PASSED, 3, paramA); + bucket.add(RollingParamEvent.REQUEST_PASSED, 1, paramB); + bucket.add(RollingParamEvent.REQUEST_PASSED, 1, paramC); + Set ascSet = bucket.ascendingKeySet(RollingParamEvent.REQUEST_PASSED); + List ascList = Arrays.asList(paramC, paramA, paramB); + int i = 0; + for(Object o : ascSet) { + assertEquals(ascList.get(i++), o); + } + List descList = Arrays.asList(paramB, paramA, paramC); + Set descSet = bucket.descendingKeySet(RollingParamEvent.REQUEST_PASSED); + i = 0; + for(Object o : descSet) { + assertEquals(descList.get(i++), o); + } + } } \ No newline at end of file