最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

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

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

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

一、項目準備

創(chuàng)建 Spring Boot 項目

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

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

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

<!-- 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>

二、編寫 Lua 腳本文件

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

腳本內(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)來加載 Lua 腳本,并保存其 SHA1 校驗碼,后續(xù)通過 EVALSHA 來調(diào)用。

創(chuàng)建腳本加載類: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;

    // 存儲腳本的 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);
    }
}

注意:

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

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

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

創(chuàng)建服務類: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 獲取值,若不存在則設置默認值并返回
     */
    public String getOrSetDefault(String key, String defaultValue) {
        return (String) redisTemplate.execute(
                LuaScriptLoader.GET_OR_SET_DEFAULT_SHA,
                Collections.singletonList(key),
                defaultValue
        );
    }
}

五、創(chuàng)建 REST 接口進行測試

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

創(chuàng)建控制器類: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);
    }
}

六、運行測試

1. 啟動 Redis 服務

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

redis-server

2. 啟動 Spring Boot 應用

使用 IDE 或命令行啟動 Spring Boot 項目:

mvn spring-boot:run

3. 測試訪問

訪問如下 URL:

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

第一次請求:

Redis 中沒有 test_lua 鍵,會自動設置為 hello_redis,并返回該值。

第二次請求:

即使不傳 defaultValue,也會返回 hello_redis,因為鍵已存在。

七、注意事項

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

八、進階建議

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

示例結(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é)

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

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

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

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

相關(guān)文章

  • Java 實戰(zhàn)項目之疫情防控管理系統(tǒng)詳解

    Java 實戰(zhàn)項目之疫情防控管理系統(tǒng)詳解

    讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實現(xiàn)一個疫情防控管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • Java程序包裝成桌面應用程序方式

    Java程序包裝成桌面應用程序方式

    這篇文章主要介紹了Java程序包裝成桌面應用程序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • DUCC配置平臺實現(xiàn)一個動態(tài)化線程池示例代碼

    DUCC配置平臺實現(xiàn)一個動態(tài)化線程池示例代碼

    這篇文章主要為大家介紹了DUCC配置平臺實現(xiàn)一個動態(tài)化線程池示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • SpringBoot war包部署到Tomcat服務器

    SpringBoot war包部署到Tomcat服務器

    這篇文章主要介紹了SpringBoot war包部署到Tomcat服務器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Java @Pointcut注解表達式案例詳解

    Java @Pointcut注解表達式案例詳解

    這篇文章主要介紹了Java @Pointcut注解表達式案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 深入理解Java線程創(chuàng)建方式(最新推薦)

    深入理解Java線程創(chuàng)建方式(最新推薦)

    作為一名Java開發(fā)者,我深刻體會到,對線程的深入理解往往區(qū)分了初級和高級程序員,在這篇文章中,我將分享我對Java線程的個人理解,從基礎概念到底層實現(xiàn),希望能為你提供有價值的見解,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • Java實現(xiàn)雪花算法的示例代碼

    Java實現(xiàn)雪花算法的示例代碼

    SnowFlow算法是Twitter推出的分布式id生成算法,主要核心思想就是利用64bit的long類型的數(shù)字作為全局的id。本文將用Java語言實現(xiàn)雪花算法,感興趣的可以學習一下
    2022-03-03
  • 百度Java面試題 前200頁精選(下)

    百度Java面試題 前200頁精選(下)

    這篇文章主要為大家分享了Java面試資源下篇,百度“Java面試題”前200頁都在這里了,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Nacos入門過程的坑--獲取不到配置的值問題

    Nacos入門過程的坑--獲取不到配置的值問題

    這篇文章主要介紹了Nacos入門過程的坑--獲取不到配置的值問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java中的Optional類用法詳細講解

    Java中的Optional類用法詳細講解

    這篇文章詳細介紹了Java中Optional類的使用,包括創(chuàng)建Optional對象,Optional對象的常用方法,如get、orElse、orElseGet、orElseThrow等,以及Optional類結(jié)合Lambda表達式和StreamAPI的使用,需要的朋友可以參考下
    2024-10-10

最新評論

邓州市| 洞口县| 黄石市| 大庆市| 齐齐哈尔市| 肇庆市| 钟祥市| 双桥区| 贵州省| 清远市| 平乐县| 文安县| 忻州市| 奎屯市| 莲花县| 鸡东县| 仙桃市| 四平市| 南康市| 乃东县| 霍山县| 伊宁市| 鹰潭市| 江永县| 岑溪市| 天门市| 中西区| 定边县| 乐安县| 河曲县| 申扎县| 拜城县| 德保县| 铜梁县| 济宁市| 巴马| 瑞昌市| 新乡市| 梧州市| 泌阳县| 沙坪坝区|