详解Java分布式IP限流和防止恶意IP攻击方案(java,分布式ip限流,防止恶意ip,编程语言)

时间:2024-05-09 07:36:09 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

    %E8%AF%A6%E8%A7%A3Java%E5%88%86%E5%B8%83%E5%BC%8FIP%E9%99%90%E6%B5%81%E5%92%8C%E9%98%B2%E6%AD%A2%E6%81%B6%E6%84%8FIP%E6%94%BB%E5%87%BB%E6%96%B9%E6%A1%88

前言

限流是分布式系统设计中经常提到的概念,在某些要求不严格的场景下,使用Guava RateLimiter就可以满足。但是Guava RateLimiter只能应用于单进程,多进程间协同控制便无能为力。本文介绍一种简单的处理方式,用于分布式环境下接口调用频次管控。

如何防止恶意IP攻击某些暴露的接口呢(比如某些场景下短信验证码服务)?本文介绍一种本地缓存和分布式缓存集成方式判断远程IP是否为恶意调用接口的IP。

思路是使用redis incr命令,完成一段时间内接口请求次数的统计,以此来完成限流相关逻辑。

这里为啥时候用lua脚本来实现呢?因为要保证incr命令和expire命令的原子性操作。KEYS[1]代表自增key值, ARGV[1]代表过期时间,ARGV[2]代表最大频次,明白了这些参数的含义,整个lua脚本逻辑也就不言而喻了。

access方法用来判断 limitKey 是否超过了最大访问频次。缓存服务对象(cacheService)的eval方法参数分别是lua脚本、key list、value list。

unlimit方法其实就是执行redis decr操作,在某些业务场景可以回退访问频次统计。

由于某些对外暴露的接口很容易被恶意用户攻击,必须做好防范措施。最近我就遇到了这么一种情况,我们一个快应用产品,短信验证码服务被恶意调用了。通过后台的日志发现,IP固定,接口调用时间间隔固定,明显是被人利用了。虽然我们针对每个手机号每天发送短信验证码的次数限制在5次以内。但是短信验证码服务每天这样被重复调用,会打扰用户并产生投诉。针对这种现象,简单的做了一个方案,可以自动识别恶意攻击的IP并加入黑名单。

思路是这样的,针对某些业务场景,约定在一段时间内同一个IP访问最大频次,如果超过了这个最大频次,那么就认为是非法IP。识别了非法IP后,把IP同时放入本地缓存和分布式缓存中。非法IP再次访问的时候,拦截器发现本地缓存(没有则去分布式缓存)有记录这个IP,直接返回异常状态,不会继续执行正常业务逻辑。

AbstractCombineCache这个抽象类封装了guava本地缓存和redis分布式缓存操作,可以降低分布式缓存压力。

没有错,IP_RATE_LUA 这个lua脚本和上面说的限流方案对应的lua脚本是一样的。

IPBlackCache继承了AbstractCombineCache,构造函数需要guava的本地Cache对象和redis分布式缓存服务ICacheService 对象。

ipAccess方法用来判断当前ip访问次数是否在一定时间内已经达到了最大访问频次。

removeIpAccess方法是直接移除当前ip访问频次统计的key值。

注入redis分布式缓存服务ICacheService对象。

通过GuavaCacheBuilder构建guava本地Cache对象,指定初始容量(initialCapacity)、最大容量(maximumSize)、并发级别、key过期时间、key移除监听器。最终要的是CacheLoader这个参数,是干什么用的呢?如果GuavaCacheBuilder指定了CacheLoader对象,那么最终创建的guava本地Cache对象是LoadingCache类型(参考AbstractCombineCache类的get方法),LoadingCache对象的get方法首先从内存中获取key对应的value,如果内存中不存在这个key则调用CacheLoader对象的load方法加载key对应的value值,加载成功后放入内存中。

最后通过ICacheService对象和guava本地Cache对象创建IPBlackCache(防止恶意IP攻击缓存服务)对象。

定义一个注解,标注在指定方法上,拦截器里会识别这个注解。

拦截器里加入ipAccess方法,校验远程IP是否为恶意攻击的IP。

remoteAddr取的是X-Forwarded-For对应的值。利用 remoteAddr 构造 cacheKey 参数,通过IPBlackCache判断 cacheKey 是否存在。

如果是 cacheKey 存在的请求,判断黑名单IP限制是否已经到达有效期,如果已经超过有效期则清除本地缓存和分布式缓存的 cacheKey ,请求合法;如果没有超过有效期则请求非法。

否则是 cacheKey 不存在的请求,使用IPBlackCache对象的ipAccess方法统计一定时间内的访问频次,如果频次超过最大限制,表明是非法请求IP,需要往IPBlackCache对象写入“ cacheKey =当前时间”。

到此这篇关于详解Java分布式IP限流和防止恶意IP攻击方案的文章就介绍到这了,更多相关Java 分布式IP限流和防止恶意IP内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

本文:详解Java分布式IP限流和防止恶意IP攻击方案的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:使用Java怎么删除二叉搜索树中的最大元素和最小元素下一篇:

21 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18