知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?

做JavaWeb的开发的同学们都应该遇到过 , 客户要求某个接口进行频次的限制 , 如每秒并发10个 , 或者短信验证码发送场景 , 60秒内只允许发送一次 。
通常开发的小伙伴们肯定是拿到以上需求在接口逻辑里进行实现 , 噼里啪啦一顿输出 , OK搞定了 , 很简单 。 的确 , 这些需求比较简单 , 但是 , 有没有想过 , 这种频次限制其实是和业务耦合度不高 , 能不能统一封装 , 在业务需要的时候直接设置就行了呢?
答案是肯定的 。 自定义注解来实现就非常的方便 , 对你的业务接口增加自定义注解 , 无需修改业务代码即可快速按需完成想要的功能 。
第一步:当然是定义一个自定义注解 , 如RateLimit
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?定义一个自定义注解RateLimit应用在方法或者类上 , 并定义相关关键字段 , 参数Key、频次数、时间、错误提示等 。 意思就是 , 在多少时间内 , 根据参数Key获取的值为判断依据 , 允许多少频次数的访问 , 如果超过 , 那么提示错误提示语 , 并拒绝访问 。
【知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?】 第二步:实现HandlerInterceptor自定义一个拦截器
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?在拦截器里重写preHandle , 将Object handler转换成HandlerMethod类型传递给自定义的securityManager处理 , 小伙伴也可以在这个地方直接实现 , 直接实现代码就不是显得那么高大上了 。
第三步:核心处理逻辑
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?核心处理方法为handle方法 , 专门处理类RateLimitHandler 。 该方法 , 获取到方法上的注解类RateLimit , 并获取到注解类里的关键信息:key()、fromHead() 。 fromHead为true表示从请求头根据key值获取对应的value值作为唯一标识uuid , 否则直接从请求参数里根据key获取唯一标识 。 获取唯一标识后 , 调用validateRate方法进行校验是否超过频次 , 传入uuid , 时间、时间单元 , 当前请求对象 。
知足常乐|如何基于spring开发自定义注解实现对接口访问频次限制?校验方法 , 首先根据uuid生成一个内部key , 用于区分不同业务 , cacheHandler是一个缓存实现 , 本例中 , cacheHandler其实注入的是redis实例 , 也可以是内存实例 。 调用cacheHandler自增方法返回一个值 , 为什么要用自增 , 是因为考虑并发情况 , 不能先get再set 。 如果为1 , 表示第一次访问 , 设置一个失效时间 , 即注解定义的多少时间内 , 在这个时间过后 , 自动失效 。
最后判断次数是否超过注解类定义的频次数 , 如果超过 , 返回false , 否则 , 返回true 。 到此 , 自定义注解的实现就结束了 。 大家疑惑 , 如果使用起来呢 。


推荐阅读