专栏首页java思维导图redis实现网关限流(限制API调用次数1000次/分)

redis实现网关限流(限制API调用次数1000次/分)

1、添加maven依赖,使用springboot2.x版本

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-pool2</artifactId>
</dependency>

2、添加redis配置进application.yml,springboot2.x版本的redis是使用lettuce配置的

spring:
  redis:
    database: 0
    host: localhost
    port: 6379
    lettuce:                  # 这里标明使用lettuce配置
      pool:
        max-active: 8         # 连接池最大连接数
        max-wait: -1ms        # 连接池最大阻塞等待时间(使用负值表示没有限制
        max-idle: 5           # 连接池中的最大空闲连接
        min-idle: 0           # 连接池中的最小空闲连接
    timeout: 10000ms          # 连接超时时间

3、使用redis作限流器有两种写法

方法一:

Long size = redisTemplate.opsForList().size("apiRequest");
if (size < 1000) {
 redisTemplate.opsForList().leftPush("apiRequest", System.currentTimeMillis());
} else {
 Long start = (Long) redisTemplate.opsForList().index("apiRequest", -1);
 if ((System.currentTimeMillis() - start) < 60000) {
  throw new RuntimeException("超过限流阈值");
 } else {
  redisTemplate.opsForList().leftPush("apiRequest", System.currentTimeMillis());
  redisTemplate.opsForList().trim("apiRequest", -1, -1);
 }
}

核心思路:用一个list来存放一串值,每次请求都把当前时间放进,如果列表长度为1000,那么调用就是1000次。如果第1000次调用时的当前时间和最初的时间差小于60s,那么就是1分钟里调用超1000次。否则,就清空列表之前的值

方法二:

Integer count = (Integer) redisTemplate.opsForValue().get("apiKey");
Integer integer = Optional.ofNullable(count).orElse(0);
if (integer > 1000) {
 throw new RuntimeException("超过限流阈值");
}
if (redisTemplate.getExpire("apiKey", TimeUnit.SECONDS).longValue() < 0) {
 redisTemplate.multi();
 redisTemplate.opsForValue().increment("apiKey", 1);
 redisTemplate.expire("apiKey", 60, TimeUnit.SECONDS);
 redisTemplate.exec();
} else {
 redisTemplate.opsForValue().increment("apiKey", 1);
}

核心思路:设置key,过期时间为1分钟,其值是api这分钟内调用次数

对比:方法一耗内存,限流准确。方法二结果有部分误差,只限制key存在的这一分钟内调用次数低于1000次,不代表任意时间段的一分钟调用次数低于1000

本文分享自微信公众号 - java思维导图(java-mindmap)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 可以实现内网穿透的几款工具

    最近没什么事情,看了一些关于内网穿透的文章,因我本身已是做微信开发相关的工作,对这部分关注的比较多,现分享给大家。

    java思维导图
  • 一个32岁入门的70后程序员给我的启示

    大家好,今天为大家带来一个非常励志,让我反思的故事。今天为大家讲的是我父亲是如何用行动教会我成为程序员的。 岁月的锤炼   圆口接口的键盘,2003 年的 ? ...

    java思维导图
  • 电商中常见的高并发怎么处理?

    在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常...

    java思维导图
  • Redis和SpringDataRedis

    Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,运行在内存中,由ANSI C编写。企业开发通常采用Redis来实现缓存。同类的产...

    宋先生
  • Oracle 19C RAC 集群日志位置变化

    有些时候,当数据库出现故障,尤其是当数据库集群无法启动时,这时候就需要查看各种日志来分析定位问题。例如db 的alert 日志,集群日志,ASM 日志,操作系统...

    JiekeXu之路
  • 关于我博客中的猫是怎么设置的说明

    点击管理--设置--往下拉,会有一个申请js权限,你需要先申请js权限,注意好措辞呦,有人说申请权限挺艰难的。我当初申请时说的是我写了不少博客了,希望美化一下自...

    绝命生
  • 人工智能助力OMO商业模式崛起

    近年来,随着我国云计算,云存储,人工智能技术的飞速发展,线上数据的不断丰富,和移动支付技术的快速普及,人工智能时代,一种新的商业模式逐渐成形。这种模式就是OMO...

    企鹅号小编
  • SignalR 2.x入门(一):SignalR简单例子

    创建空Asp.Net Web项目,在程序包管理器控制台中输入如下命令,安装SignalR:

    喵叔
  • springboot2.0.0版本报错 Load balancer does not have available server for client: sserver

    解决办法:在application.properties中配置熔断器 hystrix.command.default.execution.isolation....

    24-丰总
  • SpringCloud 之外的选择:国产JBoot v1.7.1 发布

    JBoot 是一个基于 JFinal 和 Undertow 开发的微服务框架。提供了 AOP、RPC、分布式缓存、限流、降级、熔断、统一配置中心、Opentra...

    Debian中国

扫码关注云+社区

领取腾讯云代金券