暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot 执行lua脚本打印log到redis

深文笔记 2021-06-21
2621

    

   在项目中使用 lua 脚本执行指令去操作redis,在我们java项目中是一个比较常见到常见.  但是我们一般使用都是会基于某个百度出来的文章来跑下, 能看到下效果就能ok了。那么现在问题就来了,如果是看不到效果呢?那该怎么办?继续百度,于是你会发现出来的一堆csdn什么文章都是抄来抄去,会让你一度怀疑自己的.

   

    于是今天这里就介绍一个使用 SpringBoot 来执行 lua 脚本的时候,来定位问题的操作.

     

     先来一个 lua 脚本文件内容看看

     

    local key = KEYS[1]
    local values = ARGV


    -- log 级别需要与 redis (server端的log级别是一致的.)
    -- redis.log(redis.LOG_WARNING,"接受到key值是 ---> " ..key)


    local result = {}
    for i,v in ipairs(values) do
    -- redis.log(redis.LOG_WARNING,"每次遍历v的值是 ---> " ..v)
    -- redis.log(redis.LOG_WARNING,"v类型 ---> " ..type(v))
    v = string.gsub(v,"\"","")
    -- redis.log(redis.LOG_WARNING,"替换后的值 ---> " ..v)
    local exists_result = redis.call('BF.ADD',key,v)
    -- redis.log(redis.LOG_WARNING,"每次返回的值是 ---> " ..exists_result)
    table.insert(result,exists_result)
    end
    return result

      该lua脚本做了什么事情呢?

      可以看到在for循环里面执行了 bf.add  指令.

       RedisBloom : 基于redis实现的布隆过滤器插件执行的指令,使用和安装参考地址 : https://docs.redislabs.com/latest/modules/redisbloom/

       


    紧接着,在项目中配置下.

          /**
      * 批量注入插入数据
      * @return
      */
      @Bean(name = "batchBloomFilterScript")
      public DefaultRedisScript batchBloomFilterScript(){


      DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();
      redisScript.setResultType(List.class);
      redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/BatchAddBloomFilter.lua")));
      return redisScript;


      }

         
      这里是 省掉了 redis的配置的没有贴出来.

      上面这段代码贴出来的意思,是告诉下大家是可以这样配置的。



      我们贴一个测试类, 就可以直接开干了.

            @Test
        public void loadBatchLuaScript(){


        DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();
        redisScript.setResultType(List.class);
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/BatchAddBloomFilter.lua")));


        List<String> list = new ArrayList<>();
        for(int i=0;i<10;i++){
        list.add("testaaaa"+i);
        }
        list.add("testaaa1");
        Object execute = redisTemplate.execute(redisScript, Collections.singletonList("test001"), list.toArray());
        System.out.println(execute);


        }



        往下看结果, 这里的值和上面输入的内容没对上,那是我有做过修改.

        这是redis中配置的logfile文件中的记录

        这里可以看到,我们在redis中打印出来的值前后都是带 "" 二个串的,所以我们用 bf.exists test001 "0test" 是返回的0,那就是没有匹配到的, 这里也许会有疑惑说没问题啊?其实不让, 得使用 bf.exists test \""0test"\" 转义下,多个"",才是ok的.

        难道我们程序得这么干?当然不是,于是本人在lua脚本中进行了代码修改

        v = string.gsub(v,"\"","")

        就是这行代码,将二个""给替换掉了。



        这是我们开了aof配置中记录的执行指令

        可以看到的是 aof 配置的记录,其实也就是依次解析了redis挨个执行的指令,然后使用aof配置还原的时候,也是依次解析并且执行还原回去的.






           这里于是我们在lua脚本中打印的log就写入到redis的配置文件,logfile配置的日志文件中来了.

            

            于是,我们比较好奇的点, 在开发怎么阶段,如果lua脚本出现看似没有执行,或者说执行了,返回的值都是1,我们在查询之类的操作, 却偏偏查询不出来,就可以使用这个log打印值的方式来定位问题.


            



        文章转载自深文笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论