快捷搜索:  as  test  xxx  在线电影  1111  www.ymwears.cn  test++aNd+8=8  as++aNd+8=8

如何使用redis实现分布式锁的lua脚本出现和资料说

1.lua简介

从 Redis 2.6.0 版本开始,经由过程内置的 Lua 说冥器,可以应用 EVAL 敕令对 Lua 脚本进行求值。

Redis 应用单个 Lua 说冥器去运行所有脚本,并且, Redis 也包管脚本会以原子性(atomic)的要领履行:当某个脚本正在运行的时刻,不会有其他脚本或 Redis 敕令被履行。这和应用 MULTI / EXEC 困绕的事务很类似。在其他其余客户端看来,脚本的效果(effect)要么是弗成见的(not visible),要么便是已完成的(already completed)。

2.Lua脚本设置设置设备摆设摆设流程

在resource目录下面新增一个后缀名为.lua结尾的文件

编写脚本履行内容

调用redisTemplate.execute措施履行脚本

3.lua eval:http://doc.redisfans.com//eval.html 4.本地起两个办事节点作为演示。演示代码如下:

本文采纳准时调整模拟线程去获取(链接:详解Scheduled准时调整)

应用-Dserver.port=9527,-Dserver.port=9528开启多个节点

local lock_key = KEYS[1]

local lock_value = KEYS[2]

local result = redis.call(‘SETNX’,lock_key,lock_value)

if result == 1

then

redis.call(‘SETEX’,lock_key,60,lock_value)

return result

else

return result

end

lua脚本redis客户端履行敕令如下:

redis-cli --eval xxxx.lua value value 。..。..。

ps:履行成功返回1,掉败返回0

local lock_key = KEYS[1]

local lock_value = KEYS[2]

local lock_time_out = KEYS[3]

local result = redis.call(‘SET’,lock_key,lock_value,‘EX’,lock_time_out,‘NX’)

return result

ps:履行成功返回OK,掉败返回nil

@Component

public class RedisLock {

@Autowired

private RedisTemplate redisTemplate;

private DefaultRedis《Boolean》 lock;

@Value(“${server.port}”)

private String port;

@Scheduled(cron = “0/5 * * * * *”)

public void lock {

String lock = “LockNxExJob”;

Boolean absent = false;

try {

// 获取锁

absent = luaExpress (lock, port);

if (!absent) {

System.out.println (String.format (“获取锁掉败!被%s拿走”, redisTemplate.opsForValue .get (lock)));

} else {

System.out.println (String.format (“获取锁成功!值为:%s”, redisTemplate.opsForValue .get (lock)));

}

} catch (Exception e) {

e.printStackTrace ;

} finally {

// 开释锁

if (absent) redisTemplate.delete (lock);

}

}

public Boolean luaExpress(String key, String value) {

lock = new DefaultRedis《》 ;

lock.setSource (new ResourceSource (new ClassPathResource (“lua\\redis.lua”)));

lock.setResultType (Boolean.class);

List《Object》 list = new ArrayList《》 ;

list.add (key);

list.add (value);

Boolean result = (Boolean) redisTemplate.execute (lock, list);

return result;

}

}

ps:当节点9527成功获取散播式锁,在没有履行开释锁之前,办事节点宕掉落了,节点9528则会无法获取到锁,直到设置锁的超韶光阴停止,才能得到锁。避免了单节点挂掉落了,锁不停未被开释的为难场景。

5.总结

Redis 应用单个 Lua 说冥器去运行所有脚本,并且, Redis 也包管脚本会以原子性(atomic)的要领履行:当某个脚本正在运行的时刻,不会有其他脚本或 Redis 敕令被履行,包管了只要能setnx成功就能setex。办理了办事获取锁成功,但忽然宕机,未能设置超韶光阴问题。

责任编辑 LK

您可能还会对下面的文章感兴趣: