赞
踩
第一点 导入配置
- <dependency>
- <groupId>org.redisson</groupId>
- <artifactId>redisson</artifactId>
- <version>3.12.0</version>
- </dependency>
-
-
- spring.redis.port=6379
- spring.redis.host=***.***.***.***
第二点 配置 分布式锁 和 redissonClient 的@bean配置
- @Configuration
- public class RedissonClientConfig {
- @Bean
- public RedissonClient redissonClient(){
- //创建一个Redisson配置对象 Config。
- Config config = new Config();
- //调用 useSingleServer 方法,选择单机模式,并指定 Redis 服务器的地址
- config.useSingleServer().setAddress("redis://***.***.***.***:6379");
- //调用 setConnectionMinimumIdleSize 方法,设置连接池最小空闲连接数为 10。
- config.useSingleServer().setConnectionMinimumIdleSize(10);
- //调用 Redisson.create 方法,创建一个 RedissonClient 对象,该对象可以用于连接和操作 Redis 数据库
- RedissonClient redissonClient = Redisson.create(config);
- return redissonClient;
- }
- }
- //注意:这段代码连接的 Redis 服务器地址为 "redis://***.***.***.***:6379",如果该地址是无法连接成功的话,需要确认 Redis 服务器是否已经启动,并检查网络连接是否正常。另外,还需要根据实际情况调整连接池参数,以保证系统的性能和稳定性。
第三点 可以写 简略版分布式锁
- //上锁/下锁
- @RequestMapping("/lock")
- public Result lock(Long id){
- //每一把锁 都有直接的解锁线程在底层 所以线程 无法互相开锁
- //创建锁 获取到锁对象Rlock
- RLock lock = redissonClient.getLock("category_" + id);
- try {
- //判断锁的状态
- boolean flag = lock.tryLock();
- if(!flag){
- return Result.error(501,"访问失败");
- }
- System.out.println("开始");
- //给锁加时长
- lock.lock(3, TimeUnit.SECONDS);
- //沉睡3秒
- Thread.sleep(3000L);
- System.out.println("结束");
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- //强制释放锁在 finally 块中强制释放锁,确保锁一定会被释放,避免出现死锁等问题
- lock.forceUnlock();
- }
- return Result.success(null,"成功");
- }
- //注意:需要注意的是,分布式锁的使用场景需要谨慎考虑,因为如果并发量过高,可能会造成锁争用严重,导致系统性能下降。此外,在设置锁的超时时间时,应该根据实际情况进行调整,避免锁的超时时间设置太短或太长,从而影响系统性能和稳定性。
第四点 限流操作
- //限流 每5秒执行一次 令牌桶算法
- @RequestMapping("/rateLimit")
- public Result rateLimit(Long id){
- //创建一个名为 "category_rateLimiter_" + id 的令牌桶对象,并使用 RedissonClient 对象 redissonClient 获取该令牌桶对象 RRateLimiter
- RRateLimiter rateLimiter = redissonClient.getRateLimiter("category_rateLimiter_" + id);
-
- //使用 trySetRate() 方法设置令牌发放速率,每 5 秒发放 1 个令牌
- rateLimiter.trySetRate(RateType.OVERALL,1,5, RateIntervalUnit.SECONDS);
- //使用 tryAcquire() 方法尝试从令牌桶中获取一个令牌,如果获取令牌成功,则可以进行访问;否则返回访问失败提示信息。此处限流的方式是控制请求发送的速率,使用令牌桶算法来平稳地控制进入系统的请求数量和频率
- boolean flag = rateLimiter.tryAcquire(1);
- if(!flag){
- return Result.error(501,"访问频繁");
- }
- return Result.success(null,"成功");
- }
- //注意:令牌桶算法能够平滑地限制请求的发送速率,避免系统瞬间被大量请求压垮,但是如果访问者在短时间内发起大量请求,也有可能导致系统出现性能问题。因此,在设计限流策略时,还需要对请求频率的控制进行限制,比如设置一个固定的时间窗口内最多允许发送多少个请求。
- //于 Redisson 实现的限流示例 最多容纳5个车位
- @RequestMapping("/semaphore")
- public Result semaphore(Long id){
- //限流
- RSemaphore semaphore = redissonClient.getSemaphore("category_semaphore_" + id);
- //设置信号量的容量,即最多容纳 5 个车位,使用 trySetPermits() 方法设置。
- semaphore.trySetPermits(5);
- //如果需要展示限流效果,可以使用 Thread.sleep() 方法沉睡一段时间,模拟使用者占用许可的时间
- try {
- Thread.sleep(10000);
- } catch (Exception e) {
- e.printStackTrace();
- }
- //使用 tryAcquire() 方法尝试获取一个许可,如果获取许可成功,则进入访问限制区;否则返回访问失败提示信息。此处限流的方式是使用信号量控制并发访问的数量,当已有 5 个访问者时,后续的访问者需要等待之前的访问者释放许可才能进行访问
- boolean flag = semaphore.tryAcquire(1);
- if(!flag){
- return Result.error(501,"访问受限失败");
- }
- return Result.success(null,"成功");
- }
- //注意:限流的实现必须适合具体场景,不能滥用,否则可能会影响正常业务操作,甚至导致系统崩溃。因此,在设计限流策略时,需要综合考虑请求频率、资源情况、业务特点等因素,在性能和稳定性之间寻找平衡点。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。