zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis Lua脚本实现ip限流示例

RedisIP 实现 示例 脚本 lua 限流
2023-06-13 09:19:48 时间

分布式限流最关键的是要将限流服务做成原子化,而解决方案可以使使用redis+lua或者nginx+lua技术进行实现,通过这两种技术可以实现的高并发和高性能。
首先我们来使用redis+lua实现时间窗内某个接口的请求数限流,实现了该功能后可以改造为限流总并发/请求数和限制总资源数。Lua本身就是一种编程语言,也可以使用它实现复杂的令牌桶或漏桶算法。
如下操作因是在一个lua脚本中(相当于原子操作),又因Redis是单线程模型,因此是线程安全的。

相比Redis事务来说,Lua脚本有以下优点

减少网络开销: 不使用 Lua 的代码需要向 Redis 发送多次请求, 而脚本只需一次即可, 减少网络传输;
原子操作: Redis 将整个脚本作为一个原子执行, 无需担心并发, 也就无需事务;
复用: 脚本会永久保存 Redis 中, 其他客户端可继续使用.

Lua脚本 local key = KEYS[1] 限流KEY(一秒一个)
local limit = tonumber(ARGV[1]) 限流大小
local current = tonumber(redis.call( get , key) or 0 )
if current + 1 limit then 如果超出限流大小
return 0
else 请求数+1,并设置2秒过期
redis.call( INCRBY , key, 1 )
redis.call( expire , key, 2 )
end
return 1

java代码 import org.apache.commons.io.FileUtils;
import redis.clients.jedis.Jedis;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class RedisLimitRateWithLUA {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i i++) {
new Thread(new Runnable() {
public void run() {
try {
latch.await();
System.out.println( 请求是否被执行: +accquire());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
latch.countDown();
}
public static boolean accquire() throws IOException, URISyntaxException {
Jedis jedis = new Jedis( 127.0.0.1 );
File luaFile = new File(RedisLimitRateWithLUA.class.getResource( / ).toURI().getPath() + limit.lua );
String luaScript = FileUtils.readFileToString(luaFile);
String key = ip: + System.currentTimeMillis()/1000; // 当前秒
String limit = 5 // 最大限制
List String keys = new ArrayList String
keys.add(key);
List String args = new ArrayList String
args.add(limit);
Long result = (Long)(jedis.eval(luaScript, keys, args)); // 执行lua脚本,传入参数
return result == 1;
}

运行结果

请求是否被执行:true
请求是否被执行:true
请求是否被执行:false
请求是否被执行:true
请求是否被执行:true
请求是否被执行:true
请求是否被执行:fals

从结果可看出只有5个请求成功执行

IP限流Lua脚本

参考 #l

本篇文章到此结束,如果您有相关技术方面疑问可以联系我们技术人员远程解决,感谢大家支持本站!


我想要获取技术服务或软件
服务范围:MySQL、ORACLE、SQLSERVER、MongoDB、PostgreSQL 、程序问题
服务方式:远程服务、电话支持、现场服务,沟通指定方式服务
技术标签:数据恢复、安装配置、数据迁移、集群容灾、异常处理、其它问题

本站部分文章参考或来源于网络,如有侵权请联系站长。
数据库远程运维 Redis Lua脚本实现ip限流示例