1. 程式人生 > >分散式 第2 篇 redis 分散式鎖

分散式 第2 篇 redis 分散式鎖

public interface IDistributedLock {
    boolean tryLock(String var1, Object var2);

    boolean tryLock(String var1, Object var2, int var3);

    boolean unLock(String var1, Object var2);
}
ublic class DistributedLockImpl implements IDistributedLock {
    private static final String lockScript = "local n = redis.call('setnx',KEYS[1],ARGV[1])\nif n == 1 then redis.call('expire',KEYS[1],ARGV[2]) end\nreturn n";
    @Autowired
    private RedisTemplate template;
    private Map<String, String> randomValueMap = new ConcurrentHashMap();
    private int defaultExpireTime = 3;

    public DistributedLockImpl() {
    }

    public boolean tryLock(String busiType, Object key) {
        return this.tryLock(busiType, key, this.defaultExpireTime);
    }

    public boolean tryLock(String busiType, Object key, int expire) {
        return (Boolean)this.template.execute((jedis) -> {
            String lockKey = this.getLockKey(busiType, key);
            String lockValue = this.getLockValue(busiType, key);
            boolean locked = (Long)jedis.eval("local n = redis.call('setnx',KEYS[1],ARGV[1])\nif n == 1 then redis.call('expire',KEYS[1],ARGV[2]) end\nreturn n", 1, new String[]{lockKey, lockValue, String.valueOf(expire)}) > 0L;
            if (locked) {
                this.randomValueMap.put(lockKey, lockValue);
            }

            return locked;
        });
    }

    public boolean unLock(String busiType, Object key) {
        return (Boolean)this.template.execute((jedis) -> {
            String lockedKey = this.getLockKey(busiType, key);
            String lockedValue = jedis.get(lockedKey);
            String localLockedValue = (String)this.randomValueMap.get(lockedKey);
            if (lockedValue == null) {
                this.randomValueMap.remove(lockedKey);
                return true;
            } else if (StringUtils.equals(lockedValue, localLockedValue)) {
                if (jedis.del(lockedKey) > 0L) {
                    this.randomValueMap.remove(lockedKey);
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        });
    }

    private String getLockKey(String busiType, Object key) {
        Objects.requireNonNull(busiType);
        Objects.requireNonNull(key);
        return busiType + "_" + key;
    }

    private String getLockValue(String busiType, Object key) {
        Objects.requireNonNull(busiType);
        Objects.requireNonNull(key);
        return "lock_" + busiType + "_" + key + "_" + (new SecureRandom()).nextInt();
    }
}
public class RedisTemplate {
    private IRedisClientMgr clientMgr;
    private String client = "default";

    public RedisTemplate(IRedisClientMgr clientMgr) {
        Objects.requireNonNull(clientMgr);
        this.clientMgr = clientMgr;
    }

    public <T> T execute(RedisOperate<T> operate) {
        return this.clientMgr.getClient(this.client).executeCmd(operate);
    }

    public <T> T execute(RedisOperate<T> operate, String client) {
        return this.clientMgr.getClient(client).executeCmd(operate);
    }

    public void setClient(String client) {
        this.client = client;
    }
}