1. 程式人生 > >使用redistemplate呼叫lua指令碼的簡單應用場景

使用redistemplate呼叫lua指令碼的簡單應用場景

最近學習了下lua,主要想在redis或者nginx做一些拓展,redis的資料型別很多,能幫助我們處理業務中的很多場景,從 Redis 2.6.0 版本開始,通過內建的 Lua 直譯器,可以使用 EVAL 命令對 Lua 指令碼進行求值。

redis對lua指令碼的呼叫是原子性的,所以一些特殊場景,比如像實現分散式鎖,我們可以放在lua中實現

本篇主要記錄一下使用redistemplate呼叫lua指令碼的簡單應用場景,編寫一段lua指令碼來實現ip限速

  1. 編寫用到的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完成呼叫,剩下可以編寫一些自己需要的邏輯。