背景
项目中只使用了一个外部持久化组件 redis。
目前需要实现全局的并发数控制,因此调研了一下怎么使用 redis 来实现。
还好已经有了成熟的解决方案,于是直接拿来用用。
本文最终选择了 redisson 的 RPermitExpirableSemaphore 来实现。
client 选取
redis 官方推荐的 java 客户端 有 jedis,lettuce 和 redisson。
其中 jedis 对应于 redis 的原生方法,lettuce 在 jedis 的基础上,优化的 redis 的连接池。
而 redisson 在 lettuce 的基础上,又封装了很多非常实用的数据结构。
初体验
话不多说,还是上一个例子吧。
pom 依赖
<dependencies>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.10.0</version>
</dependency>
</dependencies>
使用
import java.util.concurrent.TimeUnit;
import org.redisson.Redisson;
import org.redisson.api.RPermitExpirableSemaphore;
import org.redisson.api.RedissonClient;
public class MainRedisClient {
public static void main(String[] args) throws InterruptedException {
RedissonClient redisson = Redisson.create();
// set permits;
RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("note.abeffect");
System.out.println(semaphore.trySetPermits(5)); // true; 如果已经存在了,那就是false.
// available permits
System.out.println(semaphore.availablePermits()); // 5
// add permits
semaphore.addPermits(1);
System.out.println(semaphore.availablePermits()); // 6
// acquire
String permitId = semaphore.tryAcquire(120, 120, TimeUnit.SECONDS);
System.out.println(semaphore.availablePermits()); // 5
String permitId2 = semaphore.tryAcquire(120, 120, TimeUnit.SECONDS);
System.out.println(semaphore.availablePermits()); // 4
// print used permits count
String timeoutName = RedissonObject.suffixName(semaphore.getName(), "timeout");
System.out.println(redisson.getScoredSortedSet(timeoutName).size());
// release
semaphore.release(permitId);
System.out.println(semaphore.availablePermits()); // 5
semaphore.release(permitId2);
System.out.println(semaphore.availablePermits()); // 6
// shutdown
redisson.shutdown();
}
}
实现
观察下 redis 中的值的变化。
当前可用值存储在 key
的 string
中;
已经在用的值,存储有 {key}:timeout
的 zset
中
初始时
127.0.0.1:6379> keys *
(empty list or set)
初始化后
127.0.0.1:6379> keys *
1) "note.abeffect"
127.0.0.1:6379> type note.abeffect
string
127.0.0.1:6379> get note.abeffect
"5"
add 后
127.0.0.1:6379> get note.abeffect
"6"
acquire 后
127.0.0.1:6379> keys *
1) "note.abeffect"
2) "{note.abeffect}:timeout"
127.0.0.1:6379> type "{note.abeffect}:timeout"
zset
127.0.0.1:6379> zrange "{note.abeffect}:timeout" 0 100 withscores
1) "7536b157d06591398faa711b1861e4a7"
2) "1547109745958"
3) "5e2ff2b25e7cc90c296540f66ef5318b"
4) "1547109747182"
127.0.0.1:6379> get note.abeffect
"4"
其中的时间戳是过期时间。
释放后
127.0.0.1:6379> keys *
1) "note.abeffect"
127.0.0.1:6379> get note.abeffect
"6"
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于