java ip限制频率_Spring mvc通过访问者IP限制接口访问频率

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

环境:

spring

spring mvc

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

com.google.guava

guava

18.0

我们这次主要使用到的是Guava工具的LoadingCache 和

RateLimiter 即缓存和限流

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

/**

* 接口访问限流service,此接口主要用于针对ip地址对于接口访问的限流控制

*/

@Service

public class LoadingCacheServiceImpl implements LoadingCacheService {

LoadingCache ipRequestCaches = CacheBuilder.newBuilder()

.maximumSize(200)// 设置缓存个数

.expireAfterWrite(1, TimeUnit.DAYS)

.build(new CacheLoader() {

@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:第一次使用,哪里不对请指正,谢谢

根据qq_35284533兄弟的提示,补充IPUtil工具类代码,这个工具类是用于获取IP地址的。

package com.jufanshare.myblog.common.util;

import javax.servlet.http.HttpServletRequest;

/**

* 获取客户端IP地址

*/

public class IPUtil {

/**

* 客户端真实IP地址的方法一:

*/

public static String getRemortIP(HttpServletRequest request) {

if (request.getHeader("x-forwarded-for") == null) {

return request.getRemoteAddr();

}

return request.getHeader("x-forwarded-for");

}

/**

* 客户端真实IP地址的方法二:

*/

public static String getIpAddr(HttpServletRequest request) {

String ip="";

if(request!=null){

ip = request.getHeader("x-forwarded-for");

if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

ip = request.getHeader("Proxy-Client-IP");

}

if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

ip = request.getHeader("WL-Proxy-Client-IP");

}

if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

ip = request.getRemoteAddr();

}

}

return ip;

}

}

————————————————

版权声明:本文为CSDN博主「聚繁大BUG」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_31384551/article/details/80955215

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值