https://blog.csdn.net/qq_31384551/article/details/80955215
我們有的時候系統里面有的用戶接口為了控制訪問頻率,需要使用到,筆記走一波
環境:
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:第一次使用,哪里不對請指正,謝謝
根據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