Spring mvc通过访问者IP限制接口访问频率

我们有的时候系统里面有的用户接口为了控制访问频率,需要使用到,笔记走一波

环境:

spring

spring mvc

Guava:谷歌高并发工具,下面是maven

<!--谷歌guava高并发处理工具-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
我们这次主要使用到的是Guava工具的 LoadingCache 和 
RateLimiter 即缓存和限流
 
 

由于是在spring 环境中,所以就直接上Service代码了:


/**
 * 接口访问限流service,此接口主要用于针对ip地址对于接口访问的限流控制
 */
@Service
public class LoadingCacheServiceImpl implements LoadingCacheService {
    LoadingCache<String, RateLimiter> ipRequestCaches = CacheBuilder.newBuilder()
            .maximumSize(200)// 设置缓存个数
            .expireAfterWrite(1, TimeUnit.DAYS)
            .build(new CacheLoader<String, RateLimiter>() {
                @Override
                public RateLimiter load(String s) throws Exception {
                    return RateLimiter.create(0.2);// 新的IP初始化 (限流每秒0.1个令牌响应,即10s一个令牌)
                }
            });
    public RateLimiter getRateLimiter(String key) throws ExecutionException {
        return ipRequestCaches.get(key);
    }
}

控制器使用代码:

@Controller
@RequestMapping("/tool/upload/")
public class FileUploadController{
    @Resource
    LoadingCacheService loadingCacheService;
    /**
     * ajax上传文件
     * @param file 文件对象
     * @return
     */
    @RequestMapping("ajaxUpload")
    @ResponseBody
    public AjaxRes ajaxUpload(@RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest){
        String ipAddr = IPUtil.getIpAddr(getRequest());
        try {
            RateLimiter limiter = loadingCacheService.getRateLimiter(ipAddr);
            if(limiter.tryAcquire()){
                //获得令牌(不限制访问)
            }else {
                //未获得令牌(限制访问)
            }
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return res;
    }
}

注:主要就是把没一个用户IP的令牌桶RateLimiter给缓存起来,然后每次用户请求接口的时候就去拿一次令牌,那到令牌则不限制访问,没拿到则限制

PS:第一次使用,哪里不对请指正,谢谢


猜你喜欢

转载自blog.csdn.net/qq_31384551/article/details/80955215