Java使用lua案例
导入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
代码案例
import redis.clients.jedis.Jedis;
public class RedisLuaDemo {
private Jedis jedis;
public RedisLuaDemo(String host, int port) {
this.jedis = new Jedis(host, port);
}
public boolean decrement(String key) {
String luaScript =
"local currentValue = tonumber(redis.call('get', KEYS[1])) " +
"if currentValue and currentValue > 0 then " +
" redis.call('decr', KEYS[1]) " +
" return true " +
"else " +
" return false " +
"end";
Object result = jedis.eval(luaScript, 1, key);
return Boolean.TRUE.equals(result);
}
public static void main(String[] args) {
RedisLuaDemo rd = new RedisLuaDemo("localhost", 6379);
boolean result = rd.decrement("test");
System.out.println(result);
}
}
SpringBoot使用Lua案例
依赖导入
<!-- RedisTemplate 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redisClient 依赖-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.5</version>
</dependency>
将tpsLua.lua脚本放在resource目录下
脚本解析:获取key,key存在且值大于0则减1,返回true,否则返回fasle
local currentValue = tonumber(redis.call('get', KEYS[1]))
if currentValue and currentValue > 0 then
redis.call('decr', KEYS[1])
return true
else
return false
end
代码案例
将脚本注入bean
/**
* tps限制 lua脚本
*/
@Bean("tpsLuaScript")
public DefaultRedisScript<Boolean> script() {
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
redisScript.setLocation(new ClassPathResource("tps.lua"));
redisScript.setResultType(Boolean.class);
return redisScript;
}
编写测试代码
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class LuaTest {
@Autowired
private RedissonClient redissonClient;
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Autowired
private RedisScript<Boolean> tpsLuaScript;
@Test
public void testLua() throws InterruptedException {
String flowKey = "test";
for (int i = 0; i < 10; i++) {
Thread.sleep(10);
boolean execute1 = Optional.ofNullable(
(Boolean) redissonClient.getScript().eval(
RScript.Mode.READ_ONLY,
tpsLuaScript.getScriptAsString(),
RScript.ReturnType.BOOLEAN,
Collections.singletonList(flowKey),
Collections.emptyList())
).orElse(false);
boolean execute2 = Optional.ofNullable(
redisTemplate.execute(
tpsLuaScript,
Collections.singletonList(flowKey),
Collections.EMPTY_LIST)
).orElse(false);
log.info("{},{}", execute1, execute2);
}
}
}