Showing
2 changed files
with
48 additions
and
31 deletions
service/src/main/java/com/yoho/search/common/downgrade/persional/KeyCountWithExpiredTime.java
0 → 100644
1 | +package com.yoho.search.common.downgrade.persional; | ||
2 | + | ||
3 | +import java.util.concurrent.atomic.AtomicInteger; | ||
4 | + | ||
5 | +public class KeyCountWithExpiredTime { | ||
6 | + | ||
7 | + private AtomicInteger count; | ||
8 | + private long expiredTime; | ||
9 | + | ||
10 | + public KeyCountWithExpiredTime(long expiredTime){ | ||
11 | + this.count = new AtomicInteger(0); | ||
12 | + this.expiredTime = expiredTime; | ||
13 | + } | ||
14 | + | ||
15 | + public int incrementAndGet(long newExpiredTime){ | ||
16 | + //key已过期,过期时间设为newExpiredTime,count设为1 | ||
17 | + if(this.expiredTime<System.currentTimeMillis()){ | ||
18 | + this.resetExpiredTime(newExpiredTime); | ||
19 | + }else{ | ||
20 | + this.count.incrementAndGet(); | ||
21 | + } | ||
22 | + return this.count.get(); | ||
23 | + } | ||
24 | + | ||
25 | + //线程安全 | ||
26 | + private synchronized void resetExpiredTime(long newExpiredTime) { | ||
27 | + if (this.expiredTime < System.currentTimeMillis()) { | ||
28 | + this.expiredTime = newExpiredTime; | ||
29 | + this.count.set(1); | ||
30 | + } | ||
31 | + } | ||
32 | + | ||
33 | +} |
@@ -17,43 +17,27 @@ public class PersionalRateLimitService { | @@ -17,43 +17,27 @@ public class PersionalRateLimitService { | ||
17 | 17 | ||
18 | private static final Logger DOWNGRADE = LoggerFactory.getLogger("DOWNGRADE"); | 18 | private static final Logger DOWNGRADE = LoggerFactory.getLogger("DOWNGRADE"); |
19 | 19 | ||
20 | - @Autowired | ||
21 | - private SearchRedis searchRedis; | ||
22 | - @Autowired | ||
23 | - private SearchDynamicConfigService searchDynamicConfigService; | 20 | + private Map<String, KeyCountWithExpiredTime> keyCountMap = new ConcurrentHashMap<String, KeyCountWithExpiredTime>(); |
21 | + | ||
22 | + private Map<String, Integer> oldCountMap = new ConcurrentHashMap<String, Integer>(); | ||
24 | 23 | ||
25 | public boolean isPersionalRateLimit(String rateLimitName, PersionalRateLimitConfig limitConfig) { | 24 | public boolean isPersionalRateLimit(String rateLimitName, PersionalRateLimitConfig limitConfig) { |
26 | - return this.isRateLimit(rateLimitName, limitConfig); | 25 | + long expireTime = System.currentTimeMillis() + limitConfig.getSecond() * 1000L; |
26 | + KeyCountWithExpiredTime keyCountWithExpiredTime = keyCountMap.putIfAbsent(rateLimitName, new KeyCountWithExpiredTime(expireTime)); | ||
27 | + if (keyCountWithExpiredTime == null) { | ||
28 | + keyCountWithExpiredTime = keyCountMap.get(rateLimitName); | ||
27 | } | 29 | } |
28 | - | ||
29 | - private Map<String, Long> oldCountMap = new ConcurrentHashMap<String, Long>(); | ||
30 | - | ||
31 | - private boolean isRateLimit(String rateLimitName, PersionalRateLimitConfig limitConfig) { | ||
32 | - String redisKey = "yohosearch:rateLimit:" + rateLimitName; | ||
33 | - try { | ||
34 | - long count = searchRedis.searchValueOperations.increment(redisKey, 1).intValue(); | ||
35 | - if (count == 1) { | ||
36 | - searchRedis.searchRedisTemplate.longExpire(redisKey, limitConfig.getSecond(), TimeUnit.SECONDS); | ||
37 | - // 如果上一阶段发生降级,则打印日志 | ||
38 | - Long oldCount = oldCountMap.get(rateLimitName); | ||
39 | - if (oldCount != null) { | ||
40 | - DOWNGRADE.error("PersionalRateLimit happen ,rateLimitName is [{}], redisKey is [{}] ,count is[{}], limitConfig is [{}]", rateLimitName, redisKey, oldCount,limitConfig.toLogInfo()); | 30 | + int currentCount = keyCountWithExpiredTime.incrementAndGet(expireTime); |
31 | + if (currentCount == 1 && oldCountMap.containsKey(rateLimitName)) { | ||
32 | + DOWNGRADE.error("PersionalRateLimit happen ,rateLimitName is [{}], oldCount is[{}], limitConfig is [{}]", rateLimitName,oldCountMap.get(rateLimitName), limitConfig.toLogInfo()); | ||
41 | oldCountMap.remove(rateLimitName); | 33 | oldCountMap.remove(rateLimitName); |
42 | } | 34 | } |
43 | - } | ||
44 | - if (count > limitConfig.getLimit()) { | ||
45 | - oldCountMap.put(rateLimitName, count); | ||
46 | - return true; | ||
47 | - } | ||
48 | - return false; | ||
49 | - } catch (Exception e) { | ||
50 | - DOWNGRADE.error(e.getMessage(), e); | ||
51 | - try { | ||
52 | - searchRedis.searchRedisTemplate.delete(redisKey); | ||
53 | - } catch (Exception e2) { | ||
54 | - DOWNGRADE.error(e2.getMessage(), e2); | ||
55 | - } | 35 | + if (currentCount <= limitConfig.getLimit()) { |
56 | return false; | 36 | return false; |
57 | } | 37 | } |
38 | + oldCountMap.put(rateLimitName, currentCount); | ||
39 | + DOWNGRADE.error("PersionalRateLimit happen ,rateLimitName is [{}],currentCount is[{}], limitConfig is [{}]", rateLimitName,currentCount, limitConfig.toLogInfo()); | ||
40 | + return true; | ||
58 | } | 41 | } |
42 | + | ||
59 | } | 43 | } |
-
Please register or login to post a comment