springboot中使用redis并且執(zhí)行調(diào)試lua腳本
今天有個(gè)項(xiàng)目需要使用redis,并且有使用腳本的需求。但是因?yàn)橹皼]有寫過,所以還有一點(diǎn)點(diǎn)不熟悉,今天記錄一下。
原因:
原子操作,redis會(huì)將整個(gè)腳本作為一個(gè)整體執(zhí)行,中間不會(huì)被其他命令插入。
1、創(chuàng)建一個(gè)基本的web項(xiàng)目
文件 ->新建 -> 項(xiàng)目,選擇spring initializr ,勾選spring web 方便測(cè)試,最主要勾選 spring data redis,和下圖一樣
2、配置redis
因?yàn)槲沂菫榱藴y(cè)試redis,所以直接使用的本地的redis,你可以替換成application.yaml,或者使用環(huán)境變量替換。
#Redis服務(wù)器ip spring.redis.host=127.0.0.1 #Redis服務(wù)器連接端口 spring.redis.port=6379
注: 你不配置的話默認(rèn)值就是上面的
3、測(cè)試redis 的lua腳本
先寫個(gè)能方便測(cè)試的接口,因?yàn)槲覟榱藴y(cè)試lua 的腳本執(zhí)行,所以就沒講什么設(shè)計(jì),直接驗(yàn)證腳本
這里要做的就是刪除過期的key,同時(shí)移除hash中的key
package com.pdool.main; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.scripting.support.ResourceScriptSource; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.*; import java.util.stream.Collectors; @RestController public class TestController { @Autowired private StringRedisTemplate redisTemplate; @RequestMapping("test") public String test() { System.out.println("xxxxxxxxxxxxxx"); try { //調(diào)用lua腳本并執(zhí)行 DefaultRedisScript<Void> redisScript = new DefaultRedisScript<>(); redisScript.setResultType(Void.class);//返回類型是Long //lua文件存放在resources目錄下的redis文件夾內(nèi) Set<String> webApiRequestSet = new HashSet<>(); webApiRequestSet.add("aa"); webApiRequestSet.add("bb"); Set<String> webWebsocketRequestSet = new HashSet<>(); String shortHashKey = "abc"; String longHashKey = "def"; String delShortKeys = webApiRequestSet.stream().map((requestId) -> shortHashKey + ":" + requestId).collect(Collectors.joining(";")); String delLongKeys = webWebsocketRequestSet.stream().map((requestId) -> longHashKey + ":" + requestId).collect(Collectors.joining(";")); List<String> keys = Arrays.asList(shortHashKey, longHashKey); redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("redis/clear-local-key.lua"))); redisTemplate.execute(redisScript, keys, delShortKeys, delLongKeys); } catch (Exception e) { e.printStackTrace(); } return "sssssssss"; } }
再來看下lua腳本,這東西花了我不少的時(shí)間
local short_hash_key = KEYS[1]; local long_hash_key = KEYS[2]; local del_short_hash_keys = ARGV[1]; local del_long_hash_keys = ARGV[2]; local function tt_split(str,reps ) local resultStrList = {} string.gsub(str,'[^'..reps..']+',function ( w ) table.insert(resultStrList,w) end) return resultStrList end local del_short_key_list= tt_split(del_short_hash_keys,";") for i = 1, #del_short_key_list do local del_key = del_short_key_list[i]; redis.call("DEL", del_key) redis.call("HDEL", short_hash_key, del_key) end local del_long_key_list = tt_split(del_long_hash_keys,";") for i = 1, #del_long_key_list do local del_key = del_long_key_list[i]; redis.call("DEL", del_key) redis.call("HDEL", long_hash_key, del_key) end
4、技術(shù)點(diǎn)
1、redis 傳參可以有兩個(gè)全局變量,一個(gè)KEYS,一個(gè)是ARGV
2、redis執(zhí)行的lua 不可以有全局變量,因?yàn)闀?huì)污染環(huán)境,所以這里的function 是local
3、lua沒有線程的字符串拆分函數(shù),上面的函數(shù)是我找些unity的同學(xué)從項(xiàng)目中扒出來的
4、lua 列表的下標(biāo)從1 開始的
5、redis中執(zhí)行的lua 是 事務(wù)性的
6、lua 會(huì)阻塞線程,如果腳本太耗時(shí)會(huì)卡主服務(wù)器
5、調(diào)試方式
調(diào)試lua腳本是真的費(fèi)勁,因?yàn)樵趓edis desktop manage中不太好測(cè)試,下面說下怎么測(cè)試,如果你本機(jī)安裝了redis。
1、進(jìn)入服務(wù)關(guān)閉關(guān)閉正在運(yùn)行的服務(wù)器
2、從命令行啟動(dòng)redis
找到redis 在本機(jī)的安裝路徑,我的路徑是 C:\Program Files\Redis
打開命令行,輸入下面的命令就能啟動(dòng)redis服務(wù)器了
redis-server.exe redis.windows.conf
3、在lua腳本中增加打印
redis.log(redis.LOG_WARNING, "last_tokens " .. last_tokens)
4、運(yùn)行代碼
調(diào)用lua腳本,就可以看到下面的輸出了,如果你不想看了,就直接從服務(wù)啟動(dòng)redis就好了
注意:正式應(yīng)用的時(shí)候把log 注釋掉。
6、總結(jié)
今天主要的時(shí)間耗費(fèi)在lua 函數(shù)的定義,一直沒有搞懂怎么調(diào)用,點(diǎn)有背,碰了好多次都沒成功。
到此這篇關(guān)于springboot中使用redis并且執(zhí)行調(diào)試lua腳本的文章就介紹到這了,更多相關(guān)springboot使用redis執(zhí)行調(diào)試lua內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+Redis執(zhí)行l(wèi)ua腳本的5種方式總結(jié)
- Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐
- springboot使用redisTemplate操作lua腳本
- SpringBoot通過redisTemplate調(diào)用lua腳本并打印調(diào)試信息到redis log(方法步驟詳解)
- SpringBoot通過RedisTemplate執(zhí)行Lua腳本的方法步驟
- SpringBoot+Redis執(zhí)行l(wèi)ua腳本的方法步驟
- SpringBoot利用注解來實(shí)現(xiàn)Redis分布式鎖
- SpringBoot基于Redis的分布式鎖實(shí)現(xiàn)過程記錄
- 關(guān)于SpringBoot 使用 Redis 分布式鎖解決并發(fā)問題
- springboot+redis+lua實(shí)現(xiàn)分布式鎖的腳本
相關(guān)文章
設(shè)計(jì)模式之原型模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了設(shè)計(jì)模式之原型模式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08mybatis3使用@Select等注解實(shí)現(xiàn)增刪改查操作
這篇文章主要介紹了mybatis3使用@Select等注解實(shí)現(xiàn)增刪改查操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11springBoot基于webSocket實(shí)現(xiàn)掃碼登錄
最近做了個(gè)新項(xiàng)目,涉及到掃碼登錄。之前項(xiàng)目使用的是 ajax輪詢的方式。感覺太low了。所以這次用webSocket的方式進(jìn)行實(shí)現(xiàn),感興趣的可以了解一下2021-06-06RandomAccessFile簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
RandomAccessFile 是隨機(jī)訪問文件(包括讀/寫)的類。它支持對(duì)文件隨機(jī)訪問的讀取和寫入,即我們可以從指定的位置讀取/寫入文件數(shù)據(jù)。這篇文章主要介紹了RandomAccessFile簡介,需要的朋友可以參考下2017-05-05java后臺(tái)如何接收get請(qǐng)求傳過來的數(shù)組
這篇文章主要介紹了java后臺(tái)如何接收get請(qǐng)求傳過來的數(shù)組問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11java時(shí)間戳與日期相互轉(zhuǎn)換工具詳解
這篇文章主要為大家詳細(xì)介紹了java各種時(shí)間戳與日期之間相互轉(zhuǎn)換的工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12