一个Redis实现的分布式锁

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisLock {
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisLock.class);

    @Autowired
    protected RedisTemplate<String, String> redisTemplate;

    private static final long DEFAULT_WAIT_LOCK_TIME_OUT = 60000;//60s 有慢sql,超时时间设置长一点
    private static final long DEFAULT_EXPIRE = 80;//80s 有慢sql,超时时间设置长一点

    /**
     * 等待锁的时间,单位为ms
     *
     * @param key
     * @param timeout ms
     */
    public void lock(String key, long timeout) {
        String lockKey = generateLockKey(key);
        long start = System.currentTimeMillis();
        try {
            while ((System.currentTimeMillis() - start) < timeout) {
                if (redisTemplate.getConnectionFactory().getConnection().setNX(lockKey.getBytes(), new byte[0])) {
                    redisTemplate.expire(lockKey, DEFAULT_EXPIRE, TimeUnit.SECONDS);//暂设置为80s过期,防止异常中断锁未释放
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("add RedisLock[" + key + "].");
                    }
                    break;
                }
                TimeUnit.SECONDS.sleep(3);
            }
        } catch (Exception e) {
            unlock(lockKey);
        }
    }

    public void unlock(String key) {
        String lockKey = generateLockKey(key);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("release RedisLock[" + lockKey + "].");
        }
        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        connection.del(lockKey.getBytes());
        connection.close();
    }

    private String generateLockKey(String key) {
        return String.format("LOCK:%s", key);
    }

    public void lock(String key) {
        lock(key, DEFAULT_WAIT_LOCK_TIME_OUT);
    }

}
时间: 2024-11-07 05:36:02

一个Redis实现的分布式锁的相关文章

Redis系列文章总结:ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁

引言:最近回头看了看之前和同事一起开发的.Net Core 2.1的项目,其中在多处用到Redis实现的分布式锁,虽然在OnResultExecuting方法中做了防止死锁的处理,但在某些场景下还是会发生死锁的问题,下面我只展示部分代码: 问题: (1)这里setnx设置的值“1”,我想问,你最后del的这个值一定是你自己创建的吗? (2)图中标注的步骤1和步骤2不是原子操作,会有死锁的概率吗? 大家可以思考一下先,下面让我们带着这两个问题往下看,下面介绍一下使用Redis实现分布式锁常用的几个

基于Redis的简单分布式锁的原理

参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的加锁机制.但是到了分布式环境,单机环境中的锁就没什么作用了,因为每个节点只能获取到自己机器内存中的锁,而无法获取到其他节点的锁状态. 分布式环境中,应该用专门的分布式锁来解决需要加锁的问题.分布式锁有很多实现,Redis,zookeeper都可以.这里以Redis为例,讲述一下基于Redis的分布式

阿里JAVA面试题剖析:一般实现分布式锁都有哪些方式?使用 Redis 如何设计分布式锁?

面试原题 一般实现分布式锁都有哪些方式?使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? 面试官心理分析 其实一般问问题,都是这么问的,先问问你 zk,然后其实是要过度到 zk 关联的一些问题里去,比如分布式锁.因为在分布式系统开发中,分布式锁的使用场景还是很常见的. 面试题剖析 Redis 分布式锁 官方叫做 RedLock 算法,是 Redis 官方支持的分布式锁算法. 这个分布式锁有 3 个重要的考量点: 互斥(只能有一个客户端

redis系列:分布式锁

redis系列:分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境,另一个是集群环境下的Redis锁实现.在介绍分布式锁的实现之前,先来了解下分布式锁的一些信息. 2 分布式锁 2.1 什么是分布式锁? 分布式锁是控制分布式系统或不同系统之间共同访问共享资源的一种锁实现,如果不同的系统或同一个系统的不同主机之间共享了某个资源时,往往需要互斥

如何用redis正确实现分布式锁?

先把结论抛出来:redis无法正确实现分布式锁!即使是redis单节点也不行!redis的所谓分布式锁无法用在对锁要求严格的场景下,比如:同一个时间点只能有一个客户端获取锁. 首先来看下单节点下一般redis分布式锁的实现,其实就是个set: 加锁: /** * 尝试获取分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间 * @return 是否获取成功

基于redis实现的分布式锁

RedisLockHelper.java /** * Created by BingZhong on 2017/7/29. * * 基于Redis实现的分布式锁 */ public final class RedisLockHelper { private static Logger logger = LoggerFactory.getLogger(RedisLockHelper.class); /** * redis操作帮助类,可以是其他封装了redis操作的类 */ private Redi

如何用 redis 造一把分布式锁

基本概念 锁 wiki:In computer science, a lock or mutex (from mutual exclusion) is a synchronization mechanism for enforcing limits on access to a resource in an environment where there are many threads of execution. A lock is designed to enforce a mutual e

使用redis构建可靠分布式锁

关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺点:操作数据库消耗较大,性能较低.为了处理一些异常,会使得整个方案越来越复杂 2. 缓存实现方式 优点:性能好,实现起来较为方便. 缺点:通过超时时间来控制锁的失效时间并不是十分的靠谱. 3 zookeeper实现 优点:有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题. 缺点:性能

Redis .net 客户端 分布式锁

关于Redis分布式锁的参考链接:http://redis.io/topics/distlock. 在我们项目中,之前琢磨用:ServiceStack.Redis,发现ServiceStack.Redis收费的,每小时内操作6000次以上报错:“The free-quota limit on '6000 Redis requests per hour' has been reached……” 那么看看别的Redis客户端: StackExchange.Redis貌似不支持分布式锁,还是我不知道?