java

lua原子性计算--luaIP限制

2019-06-03  本文已影响0人  一一垚

redis eval执行lua

1.我们来做一个lua脚本提供,如果一个ip在一定时间内频繁访问,脚本返回1 否自返回0

--redis 执行 不应该出现"#!/bin/lua"
--[[ 
首先根据上述描述,需要有三个变量 ip  时间  访问超过多少次,如果超过访问次数则返回1

redis 执行lua的命令示例
redis-cli --eval 脚本名称(指向脚本的路径需要带上) KEYS,ARGV
单机redis-cli --eval limit-ip.lua  ip:limit:127.0.0.1(空格) ,(空格)10(空格)3

逗号两边一定要有空格

脚本开始首先处理参数的接收
--]]
local key=KEYS[1]
local expireTime=ARGV[1]
local times=tonumber(ARGV[2])
--[[num是当前自增后得到的数量,也就是该key自增次数,也就是该ip访问次数,如果是第一次应该设置过期时间  --]]
local num=redis.call("incr",key)
if num == 1 then
    redis.call("expire",key,expireTime)
end
if num > times then
    return 1
end
return 0


2.在并发的情况下获取redis中的值并将其与传入值相加,取值加法应是原子操作

lua原子性计算

--[[
根据描述该操作首先应该获取key 使用get该key的值 与传入值相加再次存入成功返回1
为了保证金额(精度计算)计算的准确性需要再传入 保留范围scala, 和计算结果如何舍取(如 四舍五入 或者 向上取整 或者 向下取整)
round ceil取大floor取小round 四舍五入
--]]
local key=KEYS[1]
local num=ARGV[1]
local round=ARGV[2]
local scala=ARGV[3]
if scala==nil then
    scala=2
end
local multiple=10^tonumber(scala)
if key==nil then
    return "key is nil"
end
if num==nil then
    return "num is nil"
end

local num_sum=redis.call("get",key)
num_sum=tonumber(num_sum)
if num_sum==nil then
    num_sum=0
end
num_sum=((num+num_sum)*multiple^2)/(multiple)

if ("ceil"==round ) then
-- 对结果进行取大
   num_sum=math.ceil(num_sum)/multiple
elseif("floor"==round) then
-- 对结果进行取小
    num_sum=math.floor(num_sum)/multiple
else
-- 对结果进行四舍五入
   num_sum=math.floor(num_sum+0.5)/multiple
end
num_sum=tostring(num_sum)
redis.call("set",key,num_sum)
return 1

启动脚本执行

[root@yasanggjimew13insg ~]# ./7001/redis-cli -c -p 7001 --eval ~/math.lua hello  ,  2.34 ceil

或者这样如果是减去四舍五入该值的话

[root@yasanggjimew13insg ~]# ./7001/redis-cli -c -p 7001 --eval ~/math.lua hello  ,  -2.34
上一篇 下一篇

猜你喜欢

热点阅读