From 43800d82a78730bf5bf173448e4955a62ea543cf Mon Sep 17 00:00:00 2001 From: hexiaofeng Date: Mon, 6 Jan 2025 08:05:02 +0800 Subject: [PATCH] Review redis limiter --- .../ratelimit/redisson/RedissonRateLimiter.java | 10 +++------- .../ratelimit/redisson/client/RedisClient.java | 17 +++++++++-------- .../redisson/client/RedisClientManager.java | 7 +++---- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/RedissonRateLimiter.java b/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/RedissonRateLimiter.java index 2f69cfb4..0561c616 100644 --- a/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/RedissonRateLimiter.java +++ b/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/RedissonRateLimiter.java @@ -49,7 +49,7 @@ public RedissonRateLimiter(RedisClientManager manager, RateLimitPolicy policy, S public RedissonRateLimiter(RedisClientManager manager, RateLimitPolicy policy, SlidingWindow window, String name) { super(policy, TimeUnit.MILLISECONDS); this.client = manager.getOrCreateClient(new RedisConfig(policy.getId(), option)); - this.limiter = client == null ? null : client.getRateLimiter("LiveAgent-limiter-" + policy.getId()); + this.limiter = client.getRateLimiter("LiveAgent-limiter-" + policy.getId()); if (limiter != null) { limiter.trySetRate(RateType.OVERALL, window.getThreshold(), Duration.ofMillis(window.getTimeWindowInMs())); } @@ -57,9 +57,7 @@ public RedissonRateLimiter(RedisClientManager manager, RateLimitPolicy policy, S @Override protected boolean doAcquire(int permits, long timeout, TimeUnit timeUnit) { - if (client != null) { - client.setLastAccessTime(System.currentTimeMillis()); - } + client.setLastAccessTime(System.currentTimeMillis()); try { return limiter == null || limiter.tryAcquire(permits, Duration.ofNanos(timeUnit.toNanos(timeout))); } catch (Throwable e) { @@ -70,8 +68,6 @@ protected boolean doAcquire(int permits, long timeout, TimeUnit timeUnit) { @Override protected void doClose() { - if (client != null) { - client.stop(); - } + client.close(); } } diff --git a/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClient.java b/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClient.java index 2dcd4391..0feb25f0 100644 --- a/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClient.java +++ b/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClient.java @@ -29,7 +29,7 @@ /** * Represents a Redis client managed by {@link RedisClientManager}. */ -public class RedisClient { +public class RedisClient implements AutoCloseable { private static final Logger logger = LoggerFactory.getLogger(RedissonRateLimiter.class); @@ -77,7 +77,7 @@ public void setLastAccessTime(long lastAccessTime) { * @return true if the client has expired, false otherwise */ public boolean isExpired(long timeout) { - return System.currentTimeMillis() - lastAccessTime >= timeout; + return isUseless() && System.currentTimeMillis() - lastAccessTime >= timeout; } /** @@ -91,26 +91,27 @@ public void start() { } } } + lastAccessTime = System.currentTimeMillis(); counter.incrementAndGet(); } /** - * Stop the redis client. + * Close the redis client. * If the reference count reaches zero, the client is removed by the consumer. */ - public void stop() { + public void close() { if (counter.decrementAndGet() == 0) { consumer.accept(this); } } /** - * Returns the current reference count of the Redis client. + * Checks if the endpoint is considered useless based on the counter value. * - * @return the reference count + * @return true if the counter is zero, indicating the endpoint is useless; false otherwise */ - public int getReference() { - return (int) counter.get(); + public boolean isUseless() { + return counter.get() == 0; } protected RedisConfig getConfig() { diff --git a/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClientManager.java b/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClientManager.java index 7a83fb5d..90f4f235 100644 --- a/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClientManager.java +++ b/joylive-implement/joylive-flowcontrol/joylive-flowcontrol-redisson/src/main/java/com/jd/live/agent/implement/flowcontrol/ratelimit/redisson/client/RedisClientManager.java @@ -43,7 +43,6 @@ public RedisClientManager(Timer timer) { public RedisClient getOrCreateClient(RedisConfig config) { RedisClient client = clients.computeIfAbsent(config, c -> new RedisClient(c, this::removeClient)); client.start(); - client.setLastAccessTime(System.currentTimeMillis()); return client; } @@ -54,7 +53,7 @@ public RedisClient getOrCreateClient(RedisConfig config) { */ private void removeClient(final RedisClient client) { clients.computeIfPresent(client.getConfig(), (c, v) -> { - if (v == client && v.getReference() == 0) { + if (v == client && v.isUseless()) { addTask(v); return null; } @@ -68,8 +67,8 @@ private void removeClient(final RedisClient client) { * @param client the Redis client to be recycled */ private void addTask(RedisClient client) { - timer.add("recycle-redis-client-" + client.getId(), 5000, () -> { - if (client.getReference() == 0 || client.isExpired(10000)) { + timer.add("Recycle-RedisClient-" + client.getId(), 5000, () -> { + if (client.isExpired(10000)) { client.shutdown(); } else { addTask(client);