Utoljára aktív 5 months ago

Spring boot 中 Redis 实现简易分布式锁

waynelone gist felülvizsgálása 5 months ago. Revízióhoz ugrás

1 file changed, 0 insertions, 0 deletions

RedisDistributedLockImpl.jav fájl átnevezve erre: RedisDistributedLockImpl.java

Fájl átnevezve változtatások nélkül

waynelone gist felülvizsgálása 5 months ago. Revízióhoz ugrás

1 file changed, 0 insertions, 0 deletions

gistfile1.txt fájl átnevezve erre: RedisDistributedLockImpl.jav

Fájl átnevezve változtatások nélkül

waynelone gist felülvizsgálása 5 months ago. Revízióhoz ugrás

3 files changed, 96 insertions

Demo.java(fájl létrehozva)

@@ -0,0 +1,14 @@
1 + DistributedLockParam lockParam = null;
2 + try {
3 + lockParam = new DistributedLockParam("test:lock:key");
4 + boolean lockOk = distributedLock.lock(lockParam);
5 + if (!lockOk) {
6 + return new Result().error("系统繁忙,请稍候重试");
7 + }
8 + // 执行业务逻辑
9 + } finally {
10 + // 最后强制解锁
11 + if (lockParam != null) {
12 + distributedLock.unlock(lockParam);
13 + }
14 + }

DistributedLock.java(fájl létrehozva)

@@ -0,0 +1,21 @@
1 + /**
2 + * 分布式锁
3 + */
4 + public interface DistributedLock {
5 +
6 + /**
7 + * 加锁
8 + *
9 + * @param param 加锁参数
10 + * @return 加锁是否成功
11 + */
12 + boolean lock(DistributedLockParam param);
13 +
14 + /**
15 + * 解锁
16 + *
17 + * @param param 加锁参数
18 + * @return 解锁是否成功
19 + */
20 + boolean unlock(DistributedLockParam param);
21 + }

gistfile1.txt(fájl létrehozva)

@@ -0,0 +1,61 @@
1 + import lombok.RequiredArgsConstructor;
2 + import org.apache.commons.lang3.StringUtils;
3 + import org.slf4j.Logger;
4 + import org.slf4j.LoggerFactory;
5 + import org.springframework.data.redis.core.RedisTemplate;
6 + import org.springframework.data.redis.core.script.DefaultRedisScript;
7 + import org.springframework.data.redis.core.script.RedisScript;
8 + import org.springframework.stereotype.Service;
9 +
10 + import java.util.Collections;
11 + import java.util.concurrent.TimeUnit;
12 +
13 + /**
14 + * Redis Lock
15 + **/
16 + @Service
17 + @RequiredArgsConstructor
18 + public class RedisDistributedLockImpl implements DistributedLock {
19 +
20 + private static final Logger log = LoggerFactory.getLogger(RedisDistributedLockImpl.class);
21 +
22 + private static final String UNLOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
23 + private static final Long UNLOCK_SUCCESS = 1L;
24 +
25 + private final RedisTemplate<String, String> redisTemplate;
26 +
27 + @Override
28 + @SuppressWarnings({"BusyWait", "java:S2142"})
29 + public boolean lock(DistributedLockParam param) {
30 + final long tryLockEndTime = param.getTryLockTime() + System.currentTimeMillis();
31 + while (true) {
32 + //判断是否超过了,尝试获取锁的时间
33 + if (System.currentTimeMillis() > tryLockEndTime) {
34 + return false;
35 + }
36 +
37 + // 尝试获取锁
38 + Boolean ok = redisTemplate.opsForValue().setIfAbsent(param.getKey(), param.getValue(), param.getHoldLockTime(), TimeUnit.MILLISECONDS);
39 + if (Boolean.TRUE.equals(ok)) {
40 + return true;
41 + }
42 +
43 + try {
44 + //获得锁失败,休眠50毫秒再去尝试获得锁,避免一直请求redis,导致redis cpu飙升
45 + Thread.sleep(50);
46 + } catch (InterruptedException e) {
47 + log.info(e.getMessage());
48 + }
49 + }
50 + }
51 +
52 + @Override
53 + public boolean unlock(DistributedLockParam param) {
54 + if (StringUtils.isBlank(param.getKey()) || StringUtils.isBlank(param.getValue())) {
55 + return false;
56 + }
57 + RedisScript<Long> redisScript = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
58 + Long result = redisTemplate.execute(redisScript, Collections.singletonList(param.getKey()), param.getValue());
59 + return UNLOCK_SUCCESS.equals(result);
60 + }
61 + }
Újabb Régebbi