使用redistemplate呼叫lua指令碼的簡單應用場景
阿新 • • 發佈:2018-12-10
最近學習了下lua,主要想在redis或者nginx做一些拓展,redis的資料型別很多,能幫助我們處理業務中的很多場景,從 Redis 2.6.0 版本開始,通過內建的 Lua 直譯器,可以使用 EVAL 命令對 Lua 指令碼進行求值。
redis對lua指令碼的呼叫是原子性的,所以一些特殊場景,比如像實現分散式鎖,我們可以放在lua中實現
本篇主要記錄一下使用redistemplate呼叫lua指令碼的簡單應用場景,編寫一段lua指令碼來實現ip限速
- 編寫用到的lua指令碼
local count = redis.call('incr',KEYS[1]) if count == 1 then redis.call('expire',KEYS[1],ARGV[1]) end if count > tonumber(ARGV[2]) then return 0 end return 1
把ip作為key傳入,然後對其計數+1,當超過我們傳入的限制次數(ARGV[2])時,返回0,否則返回1
2.使用redistemplate呼叫該指令碼
@Service("ipAccessService") public class IpAccessService { @Autowired private RedisTemplate<String,Object> redisTemplate; private DefaultRedisScript<Long> script; private static final String IPACCESS_KEY_PREX = "ipaccess_"; @PostConstruct private void init(){ script = new DefaultRedisScript<Long>(); script.setResultType(Long.class); script.setScriptSource(new ResourceScriptSource(new ClassPathResource("ipaccess.lua"))); } public boolean exec(String ip) { List<String> keys = new ArrayList<>(); keys.add(IPACCESS_KEY_PREX + ip); return redisTemplate.execute(script, keys, 10, 20) == 1 ? true : false; } }
主要使用redistempalte封裝的execute來實現呼叫,其中第二個引數為lua指令碼中的KEYS[1],後面為可變引數,可變引數即傳入我們需要的值,分別對應ARGV[1],ARGV[2]
3.編寫攔截器,獲取ip,注入該service傳入ip完成呼叫,剩下可以編寫一些自己需要的邏輯。