欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot集成Redis并調(diào)用Lua腳本的示例詳解

 更新時(shí)間:2025年07月17日 09:02:36   作者:超級(jí)小忍  
Redis 是一個(gè)高性能的內(nèi)存數(shù)據(jù)庫(kù),廣泛用于緩存、計(jì)數(shù)器、分布式鎖等場(chǎng)景,本文主要和大家詳細(xì)介紹了SpringBoot如何集成Redis并調(diào)用Lua腳本,需要的小伙伴可以了解下

前言

Redis 是一個(gè)高性能的內(nèi)存數(shù)據(jù)庫(kù),廣泛用于緩存、計(jì)數(shù)器、分布式鎖等場(chǎng)景。在某些業(yè)務(wù)中,我們需要對(duì)多個(gè) Redis 操作進(jìn)行原子性處理,以保證數(shù)據(jù)一致性,這時(shí)就可以使用 Redis 提供的 Lua 腳本功能。

Spring Boot 通過(guò) RedisTemplate 對(duì) Redis 進(jìn)行了良好的封裝,也支持我們方便地調(diào)用 Lua 腳本。本文將帶你一步步實(shí)現(xiàn) Spring Boot 中如何:

  • 加載 Lua 腳本
  • 調(diào)用 Lua 腳本
  • 實(shí)現(xiàn)一個(gè)實(shí)際業(yè)務(wù)邏輯:獲取 key,若不存在則設(shè)置默認(rèn)值并返回

一、項(xiàng)目準(zhǔn)備

創(chuàng)建 Spring Boot 項(xiàng)目

你可以使用 Spring Initializr 創(chuàng)建一個(gè)新項(xiàng)目,選擇以下依賴(lài):

  • Spring Web
  • Spring Data Redis
  • Lettuce(Redis 客戶端)

或者手動(dòng)創(chuàng)建 Maven 項(xiàng)目后添加如下依賴(lài):

<!-- Spring Boot Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- Web 支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Redis 支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Lettuce 客戶端 -->
<dependency>
    <groupId>io.lettuce.core</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.2.4</version>
</dependency>

二、編寫(xiě) Lua 腳本文件

我們將創(chuàng)建一個(gè)簡(jiǎn)單的 Lua 腳本:如果 key 不存在,則設(shè)置默認(rèn)值;存在則直接返回當(dāng)前值。

腳本內(nèi)容:get_or_set_default.lua

路徑建議為:src/main/resources/lua/get_or_set_default.lua

-- get_or_set_default.lua
local key = KEYS[1]
local defaultVal = ARGV[1]

local value = redis.call('GET', key)
if not value then
    redis.call('SET', key, defaultVal)
    value = defaultVal
end
return value

三、加載 Lua 腳本到 Redis

我們可以利用 Spring 的生命周期回調(diào)(如 @PostConstruct)來(lái)加載 Lua 腳本,并保存其 SHA1 校驗(yàn)碼,后續(xù)通過(guò) EVALSHA 來(lái)調(diào)用。

創(chuàng)建腳本加載類(lèi):LuaScriptLoader.java

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;

@Service
public class LuaScriptLoader {

    private final RedisTemplate<String, Object> redisTemplate;

    // 存儲(chǔ)腳本的 SHA1 值
    public static String GET_OR_SET_DEFAULT_SHA;

    public LuaScriptLoader(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @PostConstruct
    public void loadScripts() throws IOException {
        Path scriptPath = Paths.get("src/main/resources/lua/get_or_set_default.lua");
        String scriptContent = Files.readString(scriptPath);

        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(scriptContent);
        redisScript.setResultType(String.class);

        // 執(zhí)行 SCRIPT LOAD 命令加載腳本
        GET_OR_SET_DEFAULT_SHA = redisTemplate.execute(
                redisScript,
                Collections.singletonList("dummyKey"),
                "defaultValue"
        );

        System.out.println("Lua Script SHA1: " + GET_OR_SET_DEFAULT_SHA);
    }
}

注意:

  • 我們使用了一個(gè) dummyKey 和 dummyValue 來(lái)執(zhí)行一次腳本,只是為了觸發(fā)腳本加載。
  • 實(shí)際調(diào)用時(shí)使用的是 EVALSHA 命令。

四、封裝 Lua 腳本調(diào)用服務(wù)

我們創(chuàng)建一個(gè)服務(wù)類(lèi)來(lái)封裝 Lua 腳本的調(diào)用邏輯。

創(chuàng)建服務(wù)類(lèi):RedisLuaService.java

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;

@Service
public class RedisLuaService {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisLuaService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 調(diào)用 Lua 腳本:根據(jù) key 獲取值,若不存在則設(shè)置默認(rèn)值并返回
     */
    public String getOrSetDefault(String key, String defaultValue) {
        return (String) redisTemplate.execute(
                LuaScriptLoader.GET_OR_SET_DEFAULT_SHA,
                Collections.singletonList(key),
                defaultValue
        );
    }
}

五、創(chuàng)建 REST 接口進(jìn)行測(cè)試

為了方便測(cè)試,我們創(chuàng)建一個(gè)簡(jiǎn)單的接口。

創(chuàng)建控制器類(lèi):RedisLuaController.java

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/redis")
public class RedisLuaController {

    private final RedisLuaService redisLuaService;

    public RedisLuaController(RedisLuaService redisLuaService) {
        this.redisLuaService = redisLuaService;
    }

    @GetMapping("/get-or-set")
    public String getOrDefault(
            @RequestParam String key,
            @RequestParam(required = false, defaultValue = "default_value") String defaultValue) {
        return redisLuaService.getOrSetDefault(key, defaultValue);
    }
}

六、運(yùn)行測(cè)試

1. 啟動(dòng) Redis 服務(wù)

確保你本地或服務(wù)器上已經(jīng)啟動(dòng)了 Redis:

redis-server

2. 啟動(dòng) Spring Boot 應(yīng)用

使用 IDE 或命令行啟動(dòng) Spring Boot 項(xiàng)目:

mvn spring-boot:run

3. 測(cè)試訪問(wèn)

訪問(wèn)如下 URL:

http://localhost:8080/redis/get-or-set?key=test_lua&defaultValue=hello_redis

第一次請(qǐng)求:

Redis 中沒(méi)有 test_lua 鍵,會(huì)自動(dòng)設(shè)置為 hello_redis,并返回該值。

第二次請(qǐng)求:

即使不傳 defaultValue,也會(huì)返回 hello_redis,因?yàn)殒I已存在。

七、注意事項(xiàng)

項(xiàng)目說(shuō)明
腳本緩存Redis 會(huì)緩存加載過(guò)的 Lua 腳本,但重啟后失效,需重新加載
調(diào)試?yán)щyLua 腳本不能輸出日志,建議先在 Redis CLI 中測(cè)試后再集成
性能考量Lua 腳本是單線程執(zhí)行的,避免復(fù)雜運(yùn)算
異常處理在 Java 層應(yīng)對(duì)腳本執(zhí)行失敗做容錯(cuò)處理
參數(shù)傳遞KEYS 是數(shù)組,ARGV 是參數(shù)數(shù)組,順序要對(duì)應(yīng)

八、進(jìn)階建議

  • 將所有 Lua 腳本統(tǒng)一管理,使用配置中心或數(shù)據(jù)庫(kù)存儲(chǔ)
  • 結(jié)合 AOP 或攔截器,實(shí)現(xiàn) Lua 腳本調(diào)用的自動(dòng)重試機(jī)制
  • 使用 Redisson 等高級(jí)庫(kù)簡(jiǎn)化 Lua 腳本操作
  • 使用 Spring Cache 抽象層結(jié)合 Lua 腳本實(shí)現(xiàn)更復(fù)雜的緩存策略

示例結(jié)構(gòu)圖

src/
├── main/
│   ├── java/
│   │   └── com.example.demo/
│   │       ├── DemoApplication.java
│   │       ├── service/
│   │       │   ├── RedisLuaService.java
│   │       │   └── LuaScriptLoader.java
│   │       └── controller/
│   │           └── RedisLuaController.java
│   └── resources/
│       └── lua/
│           └── get_or_set_default.lua
└── pom.xml

總結(jié)

本文詳細(xì)介紹了如何在 Spring Boot 中調(diào)用 Redis 的 Lua 腳本,包括:

  • 添加必要的依賴(lài)
  • 編寫(xiě) Lua 腳本
  • 使用 RedisTemplate 加載和調(diào)用腳本
  • 構(gòu)建完整的調(diào)用流程與接口測(cè)試

Lua 腳本非常適合用來(lái)實(shí)現(xiàn)一些需要原子性的 Redis 操作,是構(gòu)建高并發(fā)系統(tǒng)的重要工具之一。

到此這篇關(guān)于SpringBoot集成Redis并調(diào)用Lua腳本的示例詳解的文章就介紹到這了,更多相關(guān)SpringBoot集成Redis調(diào)用Lua內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于maven項(xiàng)目中使用BCrypt加密方式

    關(guān)于maven項(xiàng)目中使用BCrypt加密方式

    BCrypt是一種基于Blowfish加密算法的密碼散列函數(shù),用于安全存儲(chǔ)和驗(yàn)證用戶密碼,它通過(guò)引入鹽和工作因子增加計(jì)算復(fù)雜度,有效防止彩虹表攻擊和破解,BCrypt具備適應(yīng)性工作因子、成本參數(shù)調(diào)整、迭代哈希和密鑰擴(kuò)展等特點(diǎn),被廣泛應(yīng)用于Web應(yīng)用程序的安全性設(shè)計(jì)中
    2024-10-10
  • Java遞歸算法遍歷部門(mén)代碼示例

    Java遞歸算法遍歷部門(mén)代碼示例

    這篇文章主要介紹了Java遞歸算法遍歷部門(mén)代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(7)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(7)

    下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你
    2021-07-07
  • 淺析Java中局部變量與成員變量同名解決技巧

    淺析Java中局部變量與成員變量同名解決技巧

    在剛開(kāi)始學(xué)習(xí)Java的時(shí)候,就了解了Java基礎(chǔ)中的變量,雖然知道這個(gè)以后會(huì)經(jīng)常用到,但沒(méi)想到了基本語(yǔ)法這里,竟然又冒出來(lái)了成員變量和局部變量。變來(lái)變?nèi)ヌ菀鬃屓烁銜灹?,今天我們就挑揀出?lái)梳理一下!
    2016-07-07
  • Spring?Boot中使用Spring?Retry重試框架的操作方法

    Spring?Boot中使用Spring?Retry重試框架的操作方法

    這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應(yīng)用,介紹了RetryTemplate配置的時(shí)候,需要設(shè)置的重試策略和退避策略,需要的朋友可以參考下
    2022-04-04
  • SpringBoot解決數(shù)據(jù)庫(kù)時(shí)間和返回時(shí)間格式不一致的問(wèn)題

    SpringBoot解決數(shù)據(jù)庫(kù)時(shí)間和返回時(shí)間格式不一致的問(wèn)題

    這篇文章主要介紹了SpringBoot解決數(shù)據(jù)庫(kù)時(shí)間和返回時(shí)間格式不一致的問(wèn)題,文章通過(guò)代碼示例和圖文結(jié)合的方式講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)和工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • java多線程通過(guò)CompletableFuture組裝異步計(jì)算單元

    java多線程通過(guò)CompletableFuture組裝異步計(jì)算單元

    這篇文章主要為大家介紹了java多線程通過(guò)CompletableFuture組裝異步計(jì)算單元,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Idea進(jìn)行pull的時(shí)候Your local changes would be overwritten by merge.

    Idea進(jìn)行pull的時(shí)候Your local changes would be

    這篇文章主要介紹了Idea進(jìn)行pull的時(shí)候Your local changes would be overwritten by merge.具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • IntelliJ IDEA中查看文件內(nèi)所有已聲明的方法(類(lèi)似eclipse的outline)

    IntelliJ IDEA中查看文件內(nèi)所有已聲明的方法(類(lèi)似eclipse的outline)

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中查看文件內(nèi)所有已聲明的方法(類(lèi)似eclipse的outline),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • java8升級(jí)java21方法步驟(完整pom文件升級(jí)及代碼修改)

    java8升級(jí)java21方法步驟(完整pom文件升級(jí)及代碼修改)

    在從Java?8升級(jí)至Java?211的過(guò)程中,需要對(duì)多個(gè)POM文件進(jìn)行升級(jí),涉及parent、web、service等模塊,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-11-11

最新評(píng)論