springboot中使用redis并且执行调试lua脚本

目录
  • 原因:
  • 1、创建一个基本的web项目
  • 2、配置redis
  • 3、测试redis 的lua脚本
  • 4、技术点
  • 5、调试方式
    • 1、进入服务关闭关闭正在运行的服务器
    • 2、从命令行启动redis
    • 3、在lua脚本中增加打印
    • 4、运行代码
  • 6、总结

今天有个项目需要使用redis,并且有使用脚本的需求。但是因为之前没有写过,所以还有一点点不熟悉,今天记录一下。

原因:

原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。

1、创建一个基本的web项目

文件 ->新建 -> 项目,选择spring initializr ,勾选spring web 方便测试,最主要勾选 spring data redis,和下图一样

2、配置redis

因为我是为了测试redis,所以直接使用的本地的redis,你可以替换成application.yaml,或者使用环境变量替换。

#Redis服务器ip
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379

注: 你不配置的话默认值就是上面的

3、测试redis 的lua脚本

先写个能方便测试的接口,因为我为了测试lua 的脚本执行,所以就没讲什么设计,直接验证脚本

这里要做的就是删除过期的key,同时移除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 {
            //调用lua脚本并执行
            DefaultRedisScript<Void> redisScript = new DefaultRedisScript<>();
            redisScript.setResultType(Void.class);//返回类型是Long
            //lua文件存放在resources目录下的redis文件夹内
            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脚本,这东西花了我不少的时间

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、技术点

1、redis 传参可以有两个全局变量,一个KEYS,一个是ARGV

2、redis执行的lua 不可以有全局变量,因为会污染环境,所以这里的function 是local

3、lua没有线程的字符串拆分函数,上面的函数是我找些unity的同学从项目中扒出来的

4、lua 列表的下标从1 开始的

5、redis中执行的lua 是 事务性的

6、lua 会阻塞线程,如果脚本太耗时会卡主服务器

5、调试方式

调试lua脚本是真的费劲,因为在redis desktop manage中不太好测试,下面说下怎么测试,如果你本机安装了redis。

1、进入服务关闭关闭正在运行的服务器

2、从命令行启动redis

找到redis 在本机的安装路径,我的路径是 C:\Program Files\Redis

打开命令行,输入下面的命令就能启动redis服务器了

redis-server.exe redis.windows.conf

3、在lua脚本中增加打印

redis.log(redis.LOG_WARNING, "last_tokens " .. last_tokens)

4、运行代码

调用lua脚本,就可以看到下面的输出了,如果你不想看了,就直接从服务启动redis就好了

注意:正式应用的时候把log 注释掉。

6、总结

今天主要的时间耗费在lua 函数的定义,一直没有搞懂怎么调用,点有背,碰了好多次都没成功。

到此这篇关于springboot中使用redis并且执行调试lua脚本的文章就介绍到这了,更多相关springboot使用redis执行调试lua内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot+Redis执行lua脚本的方法步骤

    1.背景 有时候,我们需要一次性操作多个 Redis 命令,但是 这样的多个操作不具备原子性,而且 Redis 的事务也不够强大,不支持事务的回滚,还无法实现命令之间的逻辑关系计算.所以,一般在开发中,我们会利用 lua 脚本来实现 Redis 的事务. 2.lua 脚本 Redis 中使用 lua 脚本,我们需要注意的是,从 Redis 2.6.0后才支持 lua 脚本的执行. 使用 lua 脚本的好处: 原子操作:lua脚本是作为一个整体执行的,所以中间不会被其他命令插入. 减少网络开销:可

  • SpringBoot通过redisTemplate调用lua脚本并打印调试信息到redis log(方法步骤详解)

    第一次写Lua脚本,并通过springboot的redisTemplate调用脚本,进行脚本与应用的交互.不熟悉真的折腾了好久,现在总结一下学习过程: 第一次写完lua时,想到的就是如何在应用调用脚本的时候,去调试脚本.在网上海搜了一把,能找到的有点相关的寥寥无几. 有一种方法是通过执行redis命令,调用redis客户端,加载lua脚本,然后出现基于命令行调试的交互界面,输入调试命令去调试脚本.如下: 在终端输入命令:redis-cli.exe --ldb --eval LimitLoadTi

  • SpringBoot通过RedisTemplate执行Lua脚本的方法步骤

    lua 脚本 Redis 中使用 lua 脚本,我们需要注意的是,从 Redis 2.6.0后才支持 lua 脚本的执行. 使用 lua 脚本的好处: 原子操作:lua脚本是作为一个整体执行的,所以中间不会被其他命令插入. 减少网络开销:可以将多个请求通过脚本的形式一次发送,减少网络时延. 复用性:lua脚本可以常驻在redis内存中,所以在使用的时候,可以直接拿来复用,也减少了代码量. 1.RedisScript 首先你得引入spring-boot-starter-data-redis依赖,其

  • SpringBoot+Redis+Lua防止IP重复防刷攻击的方法

    黑客或者一些恶意的用户为了攻击你的网站或者APP.通过肉机并发或者死循环请求你的接口.从而导致系统出现宕机. 针对新增数据的接口,会出现大量的重复数据,甚至垃圾数据会将你的数据库和CPU或者内存磁盘耗尽,直到数据库撑爆为止. 针对查询的接口.黑客一般是重点攻击慢查询,比如一个SQL是2S.只要黑客一致攻击,就必然造成系统被拖垮,数据库查询全都被阻塞,连接一直得不到释放造成数据库无法访问. 具体要实现和达到的效果是: 需求:在10秒内,同一IP 127.0.0.1 地址只允许访问30次. 最终达到

  • springboot中使用redis并且执行调试lua脚本

    目录 原因: 1.创建一个基本的web项目 2.配置redis 3.测试redis 的lua脚本 4.技术点 5.调试方式 1.进入服务关闭关闭正在运行的服务器 2.从命令行启动redis 3.在lua脚本中增加打印 4.运行代码 6.总结 今天有个项目需要使用redis,并且有使用脚本的需求.但是因为之前没有写过,所以还有一点点不熟悉,今天记录一下. 原因: 原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入. 1.创建一个基本的web项目 文件 ->新建 -> 项目,

  • springboot中使用redis的方法代码详解

    特别说明: 本文针对的是新版 spring boot 2.1.3,其 spring data 依赖为 spring-boot-starter-data-redis,且其默认连接池为 lettuce ​redis 作为一个高性能的内存数据库,如果不会用就太落伍了,之前在 node.js 中用过 redis,本篇记录如何将 redis 集成到 spring boot 中.提供 redis 操作类,和注解使用 redis 两种方式.主要内容如下: •docker 安装 redis •springboo

  • SpringBoot中使用redis做分布式锁的方法

    一.模拟问题 最近在公司遇到一个问题,挂号系统是做的集群,比如启动了两个相同的服务,病人挂号的时候可能会出现同号的情况,比如两个病人挂出来的号都是上午2号.这就出现了问题,由于是集群部署的,所以单纯在代码中的方法中加锁是不能解决这种情况的.下面我将模拟这种情况,用redis做分布式锁来解决这个问题. 1.新建挂号明细表 2.在idea上新建项目 下图是创建好的项目结构,上面那个parent项目是其他项目不用管它,和新建的没有关系 3.开始创建controller,service,dao(mapp

  • java、spring、springboot中整合Redis的详细讲解

    java整合Redis 1.引入依赖或者导入jar包 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> 2.代码实现 public class JedisTest { public static void main(String[]

  • SpringBoot中使用Redis作为全局锁示例过程

    目录 一.模拟没有锁情况下的资源竞争 二.使用redis加锁 微服务的项目中,一个服务我们启动多份,在不同的进程中.这些服务是无状态的,而由数据存储容器(mysql/redis/es)进行状态数据的持久化.这就会导致资源竞争,出现多线程的问题. 一.模拟没有锁情况下的资源竞争 public class CommonConsumerService { //库存个数 static int goodsCount = 900; //卖出个数 static int saleCount = 0; publi

  • springboot中使用redis由浅入深解析

    正文 很多时候,我们会在springboot中配置redis,但是就那么几个配置就配好了,没办法知道为什么,这里就详细的讲解一下 这里假设已经成功创建了一个springboot项目. redis连接工厂类 第一步,需要加上springboot的redis jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redi

  • 在SpringBoot中添加Redis及配置方法

    在实际的开发中,会有这样的场景.有一个微服务需要提供一个查询的服务,但是需要查询的数据库表的数据量十分庞大,查询所需要的时间很长. 此时就可以考虑在项目中加入缓存. 引入依赖 在maven项目中引入如下依赖.并且需要在本地安装redis. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifac

  • SpringBoot中使用Redis的完整实例

    一.在SpringBoot中使用Redis的一套军体拳 1.导包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.2.0.RELEASE</version> </dependency> 2.导入工具类 packag

  • 使用SpringBoot中整合Redis

    目录 SpringBoot中整合Redis SpringBoot整合Redis改不了database问题 SpringBoot中整合Redis 本次,我们以IDEA + SpringBoot作为 Java中整合Redis的使用 的测试环境,如果对创建SpringBoot项目有不清楚的地方,可以参考这篇文章:使用Idea创建我的第一个SpringBoot项目 首先,我们需要导入Redis的maven依赖 <!-- Redis的maven依赖包 -->         <dependency

  • SpringBoot中使用Redis Stream实现消息监听示例

    目录 Demo环境 仓库地址 POM依赖 配置监听消息类 监听俩个stream的实现 [问题补充]确认完消息删除消息 [问题补充]自动初始化stream的key和group问题-最新更新-2021年12月4日 Demo环境 JDK8 Maven3.6.3 springboot2.4.3 redis_version:6.2.1 仓库地址 https://gitee.com/hlovez/redismq.git. POM依赖 <?xml version="1.0" encoding=

随机推荐