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

心已赠人 2022-05-21 13:10 480阅读 0赞

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

环境:

spring

spring mvc

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

  1. <!--谷歌guava高并发处理工具-->
  2. <dependency>
  3. <groupId>com.google.guava</groupId>
  4. <artifactId>guava</artifactId>
  5. <version>18.0</version>
  6. </dependency>

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

  1. RateLimiter 即缓存和限流

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

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

控制器使用代码:

  1. @Controller
  2. @RequestMapping("/tool/upload/")
  3. public class FileUploadController{
  4. @Resource
  5. LoadingCacheService loadingCacheService;
  6. /**
  7. * ajax上传文件
  8. * @param file 文件对象
  9. * @return
  10. */
  11. @RequestMapping("ajaxUpload")
  12. @ResponseBody
  13. public AjaxRes ajaxUpload(@RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest){
  14. String ipAddr = IPUtil.getIpAddr(getRequest());
  15. try {
  16. RateLimiter limiter = loadingCacheService.getRateLimiter(ipAddr);
  17. if(limiter.tryAcquire()){
  18. //获得令牌(不限制访问)
  19. }else {
  20. //未获得令牌(限制访问)
  21. }
  22. } catch (ExecutionException e) {
  23. e.printStackTrace();
  24. }
  25. return res;
  26. }
  27. }

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

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

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

  1. package com.jufanshare.myblog.common.util;
  2. import javax.servlet.http.HttpServletRequest;
  3. /**
  4. * 获取客户端IP地址
  5. */
  6. public class IPUtil {
  7. /**
  8. * 客户端真实IP地址的方法一:
  9. */
  10. public static String getRemortIP(HttpServletRequest request) {
  11. if (request.getHeader("x-forwarded-for") == null) {
  12. return request.getRemoteAddr();
  13. }
  14. return request.getHeader("x-forwarded-for");
  15. }
  16. /**
  17. * 客户端真实IP地址的方法二:
  18. */
  19. public static String getIpAddr(HttpServletRequest request) {
  20. String ip="";
  21. if(request!=null){
  22. ip = request.getHeader("x-forwarded-for");
  23. if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  24. ip = request.getHeader("Proxy-Client-IP");
  25. }
  26. if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  27. ip = request.getHeader("WL-Proxy-Client-IP");
  28. }
  29. if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  30. ip = request.getRemoteAddr();
  31. }
  32. }
  33. return ip;
  34. }
  35. }

发表评论

表情:
评论列表 (有 0 条评论,480人围观)

还没有评论,来说两句吧...

相关阅读