LUA语言介绍
LUA脚本语言是C开发的,类似存储过程
使用LUA脚本的好处
1.减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行
2.原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令 插入。换句话说,编写脚本的过程中无需担心会出现竞态条件
3.复用性,客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑
LUA编译器安装
- Lua在linux中的安装
- 到官网下载lua的tar.gz的源码包
wget http://www.lua.org/ftp/lua-5.3.5.tar.gz .
tar -zxvf lua-5.3.0.tar.gz
- 进入解压的目录:
cd lua-5.2.0
make linux
make install
- 如果报错,说找不到readline/readline.h, 可以通过yum命令安装
yum -y install libtermcap-devel ncurses-devel libevent-devel readline-devel
- 安装完以后再make linux / make install
- 最后,直接输入 lua命令即可进入lua的控制台
LUA 基本语法
and break do else
elseif end false for
function if in local
nil not or repeat
return then true until
while
LUA 数据类型
Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。
LUA 例子 语法1
local int sum =0;
local int i = 0;
while i <= 100
do sum = sum + i
i = i + 1
end
print(sum)
语法二:
local tables myArray=["james","java","false",34] // 定义
local int sum = 0;
print(myArray[3]) // 返回false
for i = 1, 100
do
sum = sum + 1
end
print(sum)
for j = 1, #myArray //遍历数组
do
print(myArray[j])
if myArray[j] == "james"
then
print("true")
break
else
print("false")
end
end
6379>eval "return redis.call('get',KEYS[1])" 1 name //eval+脚本+KEYS[1]+键个数+键
语法:eval script numkeys key [key ...]
LUA执行流程
Lua 脚本管理
1. ./redis-cli -h 192.168.42.111 -a 12345678 script load "$(cat xxxx.lua)" //将LUA脚本内容加载到redis, 得到 返回的sha1值: xxxxxx
2. 6379〉script exists xxxx//检查sha1值的LUA脚本是否加载到redis中, 返回1 已加载成功
3.6379〉script flush //清空加载的lua脚本内容
4.6379〉script kill //杀掉正在执行的LUA脚本,比如LUA比较耗时阻塞,
限流方式
1. 限制总并发数
比如数据库连接池、线程池
2.限制瞬时并发数
如nginx的limit_conn模块,用来限制瞬时并发连接数
3. 限制时间窗口内的平均速率
如Guava的RateLimiter、nginx的limit_req模块,限制每秒平均速率
4.其它限制
如限制远程接口调用速率、限制MQ的消费速率
使用Java 实现限流
案例-实现访问频率限制: 实现访问者 $ip 127.0.0.1在一定的时间 $time 20S内只能访问 $limit 10次.使用JAVA语言实现如下:
private boolean accessLimit (String ip, int limit, int time, Jedis jedis) {
boolean result = true;
String key = "rate.limit" + ip;
if(jedis.exists(key)) {
long after Value = jedis.incr(key);
if(afterValue > limit) {
return = false
}
}else {
Transaction transaction = jedis.multi();
transation.incr(key);
transation.expire(key, time);
transation.exec();
}
return result;
}
Redis + Lua 实现限流