赞
踩
Redisson可以实现很多东西,在Redis的基础上,Redisson做了超多的封装,不仅可以用来实现分布式锁,还可以帮助我们实现令牌桶限流。
Ratelimter主要作用就是可以限制调用接口的次数。主要原理就是调用接口之前,需要拥有指定个令牌,限流器每秒会产生X个令牌放入令牌桶,调用接口需要去令牌桶里面拿令牌。如果令牌被其它请求拿完了,那么自然而然,当前请求就调用不到指定的接口。
RateLimter实现限流
- @RestController
- @RequestMapping("/redisTest")
- public class RedisTestController {
-
- @Autowired
- private Redisson redisson;
-
-
- @GetMapping("/Token")
- public String testTokenBucket() {
- RRateLimiter rateLimiter = redisson.getRateLimiter("myRatelimiter");
-
- //最大流速 =每10秒钟产生1个令牌
- rateLimiter.trySetRate(RateType.OVERALL, 1, 10, RateIntervalUnit.SECONDS);
-
- //需要1个令牌
- if (rateLimiter.tryAcquire(1)) {
- return "令牌桶里面有可使用的令牌";
- }
- return "不好意思,请过十秒钟再来~~~~~~~";
- }
- }
话不多说直接上代码,如下:
- package com.shop.cyshop.commons.service;
-
- /**
- * 限流器
- *
- * @date 2024年04月28日 15:02
- */
-
- import com.shop.cyshop.commons.locker.LockService;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
-
- import java.util.concurrent.TimeUnit;
-
- @Service
- @Slf4j
- public class RequestLimitService {
-
- private static final String REQUEST_LIMIT_KEY = "request_limit";
- private static final int WINDOW_SIZE_SECONDS = 6; //每六秒一次请求限制
- private static final int MAX_REQUESTS = 1;
-
- @Autowired
- private RedisTemplate<String, String> redisTemplate;
-
- @Autowired
- private LockService lockService;
-
- public boolean isAllowed() {
- return lockService.lock(REQUEST_LIMIT_KEY + "::glock", "sys", () -> {
- long currentTime = System.currentTimeMillis() / 1000; //10
- long windowStart = currentTime - WINDOW_SIZE_SECONDS;//4
-
- // 删除过期的记录
- redisTemplate.opsForZSet().removeRangeByScore(REQUEST_LIMIT_KEY, 0, windowStart);
-
-
- // 获取当前窗口内的请求数量
- Long currentRequests = redisTemplate.opsForZSet().count(REQUEST_LIMIT_KEY, windowStart, currentTime);
-
- if (currentRequests != null && currentRequests < MAX_REQUESTS) {
- // 增加请求记录
- redisTemplate.opsForZSet().add(REQUEST_LIMIT_KEY, String.valueOf(currentTime), currentTime);
- // 设置过期时间
- redisTemplate.expire(REQUEST_LIMIT_KEY, WINDOW_SIZE_SECONDS, TimeUnit.SECONDS);
- return true;
- }
- return false;
- });
- }
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。