介绍一个基于Spring Redis Lua的无侵入应用级网关限流框架

  • 项目介绍
    • 为什么选择spring-redis-current-limit
  • Quick Start
    • 1. 引入spring-redis-current-limit
    • 2. 注册spring-redis-current-limit
      • 1.SpringBoot或SpringCloud项目
      • 2.Spring项目
    • 3. 配置您的redis连接
      • 1.SpringBoot或SpringCloud项目
      • 2. Spring应用
    • 4. 使用spring-redis-current-limit
      • spring-redis-current-limit为您提供了一个注解@CurrentLimit来进行限流。您可以将它用在类上或方法上。
  • 更多信息
    • 限流算法
    • 再次开发
    • 作者信息
    • 参考
    • 版本信息
      • 1.0.0

项目介绍

此项目是基于Spring Redis Lua的无侵入应用级网关限流框架,如果您正在寻找一个网关限流的框架,使用spring-redis-current-limit是最明智的选择

为什么选择spring-redis-current-limit

  1. 无需任何复杂配置文件,一个注解玩转spring-redis-current-limit
  2. 细粒度控制,您可以控制同一个类中的A方法每分钟限流100而B方法每分钟限流200
  3. 高灵活性,可根据自定义信息(如用户id、用户ip、用户权限等)进行限流、可灵活选择限流算法
  4. 高可用性,使用redis+lua脚本的原子性为分布式系统保驾护航
  5. 高可扩展性,可灵活添加限流算法

Quick Start

1. 引入spring-redis-current-limit

<dependency><groupId>com.github.chqiuu</groupId><artifactId>spring-redis-current-limit</artifactId><version>Latest Version</version></dependency>

2. 注册spring-redis-current-limit

因为并不是所有的项目都会使用SpringBoot,所以在注册这一步我们分为两种情况

1.SpringBoot或SpringCloud项目

您需要在启动类上增加一个注解

@EnableCurrentLimit
@SpringBootApplication
public class StudyApplication {public static void main(String[] args) {SpringApplication.run(StudyApplication.class, args);}
}

2.Spring项目

您需要提供一个可以被Spring管理的配置类。比如说:

@Import(EnableCurrentLimitConfiguration.class)
@Configuration
public class CurrentLimitConfig {}

3. 配置您的redis连接

您需要配置您的redis连接为spring-redis-current-limit,同2的情况我们把项目分为两种情况(注意下方的配置需要根据实际情况调整)

1.SpringBoot或SpringCloud项目

spring:redis:host: port: password:timeout: 2000

2. Spring应用

您只需要注册一个RedisConnectionFactory子类的bean。比如说

<beans><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" ><property name="maxIdle" value="${redis.maxIdle}" /><property name="maxWaitMillis" value="${redis.maxWait}" /><property name="testOnBorrow" value="${redis.testOnBorrow}" /></bean><bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" ><property name="poolConfig" ref="poolConfig" /><property name="port" value="${redis.port}" /><property name="hostName" value="${redis.host}" /><property name="timeout" value="${redis.timeout}" ></property><property name="database" value="1"></property></bean>
</beans>

4. 使用spring-redis-current-limit

其实看到这一步的时候您已经可以使用spring-redis-current-limit来进行限流了哦。

spring-redis-current-limit为您提供了一个注解@CurrentLimit来进行限流。您可以将它用在类上或方法上。

接下来介绍一下注解中的几个属性

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CurrentLimit {/*** 设置限流条件唯一标识,默认为系统自动生成。建议不配置此项,若想要配置请保证此项的唯一性** @return 限流条件唯一标识*/String key() default "";/*** 设置提示消息** @return 被限流时的提示消息*/String message() default "您的手速太快了,请稍后再试";/*** 设置给定的时间范围 单位(秒)** @return 给定的时间范围 单位(秒)。默认值60*/long interval() default 60;/*** 设置单位时间内可访问次数(限流次数)* 当为令牌桶算法时,为向令牌桶中添加数据的时间间隔, 以秒为单位。默认值10秒** @return 单位时间内可访问次数(限流次数)。默认值10*/long limit() default 10;/*** 设置每次为令牌桶中添加的令牌数量** @return 每次为令牌桶中添加的令牌数量。默认值5个*/long step() default 5;/*** 设置限流类型。默认值:LOCAL*/LimitTypeEnum limitType() default LimitTypeEnum.LOCAL;/*** 设置在类上设置注解限流模式,当为ElementType.TYPE时有效** @return 在类上设置注解限流模式*/TypeLimitModelEnum typeLimitModel() default TypeLimitModelEnum.EACH;
}

来几个使用的例子吧

  1. 限流一个Controller中的所有接口。(例如,需要每个方法每5秒只允许调用3次)
@CurrentLimit(interval = 5, limit = 3, message = "在类上做限流,每个接口每5秒只能访问3次,您已经超过3次访问,请稍后再试")
@RestController
@RequestMapping("/type/each")
public class TypeEachCurrentLimitController {private static final AtomicInteger ATOMIC_INTEGER_HAVE_PARAM = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_NO_PARAM = new AtomicInteger();@GetMapping("/haveParam")public String haveParam(String param) {return String.format("第%s次访问【param:%s】,成功获得数据!", ATOMIC_INTEGER_HAVE_PARAM.incrementAndGet(), param);}@GetMapping("/noParam")public String noParam() {return String.format("第%s次访问,成功获得数据!", ATOMIC_INTEGER_NO_PARAM.incrementAndGet());}
}
  1. 根据IP限流访问次数
//每个IP每20秒可以访问5次
@CurrentLimit(interval = 20, limit = 5, limitType = LimitTypeEnum.IP, message = "IP,您的手速太快了,请稍后再试")
  1. 限流某个方法的并发数
@RestController
@RequestMapping("/method")
public class MethodLimiterController {private static final AtomicInteger ATOMIC_INTEGER_LOCAL = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_IP = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_USER = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_SESSION = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_CUSTOM = new AtomicInteger();@CurrentLimit(interval = 5, limit = 3, message = "此方法对所有来源的请求都限流,5秒只能访问3次,您已经超过3次访问,请稍后再试")@GetMapping("/local")public String local() {return String.format("第%s次访问,成功获得数据!", ATOMIC_INTEGER_LOCAL.incrementAndGet());}@CurrentLimit(interval = 5, limit = 3, message = "此方法访问根据IP限流,5秒只能访问3次,您已经超过3次访问,请稍后再试")@GetMapping("/ip")public String ip() {return String.format("第%s次访问,成功获得数据!", ATOMIC_INTEGER_IP.incrementAndGet());}@CurrentLimit(interval = 5, limit = 3, message = "此方法访问根据用户限流,5秒只能访问3次,您已经超过3次访问,请稍后再试")@GetMapping("/user")public String user() {return String.format("第%s次访问,成功获得数据!", ATOMIC_INTEGER_USER.incrementAndGet());}@CurrentLimit(interval = 5, limit = 3, message = "此方法访问根据Session限流,5秒只能访问3次,您已经超过3次访问,请稍后再试")@GetMapping("/session")public String session() {return String.format("第%s次访问,成功获得数据!", ATOMIC_INTEGER_SESSION.incrementAndGet());}@CurrentLimit(interval = 5, limit = 3, limitType = LimitTypeEnum.CUSTOM, message = "此方法为自定义限流,5秒只能访问3次,您已经超过3次访问,请稍后再试")@GetMapping("/custom")public String testLimiter2(HttpServletRequest request) {//根据一系列操作查出来了用户id//限流时在httpServletRequest中根据Const.CUSTOM的值进行限流request.setAttribute(Constant.CUSTOM, "user_id");return String.format("第%s次访问,成功获得数据!", ATOMIC_INTEGER_CUSTOM.incrementAndGet());}
}
  1. 更多示例请移步演示示例

更多信息

相信看完了上方的Quick Start您已经迫不及待的想要将spring-redis-current-limit应用于生产了。我在这里为您提供了两种限流算法。您可以根据自己系统的需求选择自己需要的算法

限流算法

如果您对限流算法不太了解的话可以先参考一下这篇文章高并发系统的限流方案研究,其实限流实现也不复杂

  1. 令牌桶算法

    程序默认使用令牌桶算法进行限流,如果您要使用令牌桶算法的话无需要额外的配置。

  2. 计数器算法

    如果您想要使用计数器算法的话,只需要增加一个配置即可。在配置文件中指定算法为计数器算法。(推荐您使用yml文件)

    1. yml配置方式
    current-limit:algorithm: counter
    
    1. properties配置方式
    current-limit.algorithm = counter
    

再次开发

如果您想使用别的算法,您可以fork项目进行开发

作者信息

  1. 个人博客
  2. GitHub

参考

将JAR包发布到Maven中央仓库
在Maven中央存储库中发布github项目

版本信息

1.0.0

spring-redis-current-limit 正式上线

介绍一个基于Spring Redis Lua的无侵入应用级网关限流框架相关推荐

  1. 保姆级的一个基于spring boot开发的前后端分离商城教程

    前言 推荐一个基于spring boot开发前后端分离商城,有完整的代码笔记和视频教程,希望对正在找项目练手的同学有所帮助 本文资料文档领取(在文末) 一.项目背景 5中常见的电商模式 B2B .B2 ...

  2. maven多模块项目部署到服务器,GitHub - baxias/foweb: 一个基于 Spring+SpringMVC+Mybatis 的Maven多模块项目。(实现前后端分离的服务器端)...

    Foweb Framework A multi-modules maven project base on Spring+SpringMVC+Mybatis. 一个基于 Spring+SpringMV ...

  3. spring boo_为您的下一个基于Spring的应用程序考虑使用spring-boot的原因!

    spring boo Spring-boot提供了一种创建基于Spring的应用程序的快速方法. 对于下一个项目,有一些非常令人信服的理由考虑使用Spring-boot: 原因1:使用spring-b ...

  4. 为您的下一个基于Spring的应用程序考虑使用spring-boot的原因!

    Spring-boot提供了一种创建基于Spring的应用程序的快速方法. 对于下一个项目,有一些非常令人信服的理由考虑使用Spring-boot: 原因1:使用spring-boot启动程序项目进行 ...

  5. 自荐Mall4j项目一个基于spring boot的Java开源商城系统

    前言 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样 ...

  6. Spring Cloud :Gateway 网关限流(五)

    目录 一.概述 1. 为什么需要限流 二.限流算法 1. 计数器算法 2. 漏桶算法 3. 令牌桶算法 四.Gateway 限流 1. 添加依赖 2. 配置文件 3. 限流规则配置类 Spring C ...

  7. 【限流02】限流算法实战篇 - 手撸一个单机版Http接口通用限流框架

    本文将从需求的背景.需求分析.框架设计.框架实现几个层面一步一步去实现一个单机版的Http接口通用限流框架. 一.限流框架分析 1.需求背景 微服务系统中,我们开发的接口可能会提供给很多不同的系统去调 ...

  8. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...

  9. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战

    文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...

最新文章

  1. Swift的类,及存储属性,计算发发样码
  2. Yarn框架和工作流程研究
  3. 三丰三坐标编程基本步骤_数控车床编程,经典实例教程
  4. 如何将Emacs添加到右键菜单并显示为“烤肉”
  5. PHP 从结果集中取得一行作为关联数组:
  6. springMVC中数据流解析与装载
  7. 动态规划入门——斐波那契数(Leetcode 509)
  8. 【转】windows多线程CreateThread与_beginthreadex本质区别
  9. 我的 2018 年终总结
  10. bitnami redmine mysql_linux下bitnami一键安装redmine后无法远程访问mysql的问题
  11. 使用TSQL语句操作MySQL数据库
  12. 命名实体识别NER探索(5) Bert+BiLSTM+CRF模型实战应用
  13. JAVA 16进制转字符串问题
  14. dtft性质及证明_信号处理基础-- DTFT、DFT和STFT基本概念
  15. Linux获取电信超级密码,电信光猫-华为HG8245C获取超级管理员密码
  16. 一维数组与二维数组的区别
  17. 机械工业品电商平台后台开发(一):项目简介及SpringMVC工作原理(工作流程)介绍
  18. 微信小程序怎么开通(自己申请开通微信小程序的方法)
  19. 基于Hyperlynx VX.2.5 的DDR3仿真之一:Verifying That the Software Recognizes Your Design Correctly
  20. python 折线图变成直线图_python如何画折线图

热门文章

  1. python 学习笔记(下)
  2. 达观资讯推荐系统助力打造更懂用户的新闻客户端
  3. uni-App小程序、canvas 生成海报 +下载图片+分享微信好友
  4. 魅族应用上传应用市场空包签名的问题,快捷解决方案!
  5. 利用new Map()做多选
  6. PhpStorm 中如何配置 PHP 语言的版本
  7. php 多张图片接口,如何利用PHP拼接多张图片为一张长图?
  8. Mac小技巧 苹果Mac系统如何删除其他多余的管理员账户
  9. 5G工业路由器助力AGV小车完成质的飞跃
  10. FFmpeg 开发(07):FFmpeg + OpenGLES 实现 3D 全景播放器