Spring mvc通过访问者IP限制接口访问频率 心已赠人 2022-05-21 13:10 359阅读 0赞 我们有的时候系统里面有的用户接口为了控制访问频率,需要使用到,笔记走一波 环境: 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][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; } } [qq_35284533]: https://me.csdn.net/qq_35284533
还没有评论,来说两句吧...