当前位置:网站首页>Redis + lua implements distributed interface current limiting implementation scheme

Redis + lua implements distributed interface current limiting implementation scheme

2022-08-11 07:14:00 CSDN cloud computing

97b0036f4cf570c460567e229cc404e5.gif

作者 | 步尔斯特

来源 | 步尔斯特

前言

redis + lua脚本已然成为了单体项目主流的限流方案.

redis凭借其特性成为了中间件的佼佼者,最新官方测试数据:

  • 读的速度是110000次/s

  • 写的速度是81000次/s.

lua:

  • 减少网络开销:使用Lua脚本,无需向Redis 发送多次请求,执行一次即可,减少网络传输

  • 原子操作:Redis 将整个Lua脚本作为一个命令执行,原子,无需担心并发

  • 复用:Lua脚本一旦执行,会永久保存 Redis 中,,其他客户端可复用

操作

在需要限流的接口处添加如下注解(@RedisLimit),在原有基础上,无需添加任何依赖即可实现限流.

@RedisLimit(name = "订单秒杀", prefix = "seckill", key = "distributed", count = 1, period = 1, limitType = LimitType.IP, msg = "当前排队人数较多,请稍后再试!")
@GetMapping("/limit/distributed/{id}")
public ResponseEntity<Object> limitDistributed(@PathVariable("id") String id) {

    return ResponseEntity.ok("成功购买:" + id + "个");
}

介绍

/**
 * 资源名称
 */
String name() default "";

/**
 * 前缀
 */
String prefix() default "";

/**
 * 资源key
 */
String key() default "";

/**
 * 最多访问次数
 */
int count();

/**
 * 时间,秒级
 */
int period();

/**
 * 类型
 */
LimitType limitType() default LimitType.CUSTOMER;

/**
 * 提示信息
 */
String msg() default "系统繁忙,请稍后再试";

功能

  • 默认根据全局接口的QPS作为流控指标

  • 可在独立IP和全局接口自由切换

  • 可自定义时间及规定时间内的QPS

  • 可根据key值做后期的数据监控和统计

原理

  • 以流量作为切点、滑动时间窗口作为核心算法.

  • lua脚本以保证其原子性操作

核心代码(部分展示)

lua脚本

redis.replicate_commands();
local listLen,time
listLen = redis.call('LLEN', KEYS[1]) 
if listLen and tonumber(listLen) < tonumber(ARGV[1]) then
local a = redis.call('TIME');
redis.call('LPUSH', KEYS[1], a[1]*1000000+a[2]) 
else
time = redis.call('LINDEX', KEYS[1], -1)
local a = redis.call('TIME');
if a[1]*1000000+a[2] - time < tonumber(ARGV[2])*1000000 then
return 0;
else
redis.call('LPUSH', KEYS[1], a[1]*1000000+a[2])
redis.call('LTRIM', KEYS[1], 0, tonumber(ARGV[1])-1)
end
end
return 1;

切点处理

Long number = redisTemplate.execute(SECKILL_SCRIPT, keys, count, period);
if(number != null && number.intValue() == 1){
                return pjp.proceed();
            }

dcb933339e53e42bef747c4a46437b38.gif

往期推荐

一篇文章了解 Docker 的安装、Start up and how it works!

剖析 kubernetes 集群内部 DNS 解析原理

Docker 镜像和容器的导入导出及常用命令

如何从 Docker Extract from mirror dockerfile!

c97ef7a38d18249044ca2f98160430e0.gif

点分享

be027d0d9763bfaa3b35730c7696b21f.gif

点收藏

696a8f41cfcd6e023326ca072cafad24.gif

点点赞

1f90725723055c3630018bd99d272314.gif

点在看

原网站

版权声明
本文为[CSDN cloud computing]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/223/202208110520399793.html