基于redis集群实现的分布式锁,可用于秒杀,定时器。
在分布式系统中,经常会出现需要竞争同一资源的情况,使用redis可以实现分布式锁。
前提:redis集群已经整合项目,并且可以直接注入JedisCluster使用:
- @Autowired
- private JedisCluster jedisCluster;
1. 新建RedisLockManger分布式锁管理器,并且如上注入 JedisCluster :
- package com.jarfk.util.redis;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import redis.clients.jedis.JedisCluster;
- import javax.annotation.PostConstruct;
- import java.util.concurrent.TimeUnit;
- /**
- * redis集群分布式锁管理器,支持对单个资源加锁解锁,或给一批资源的批量加锁及解锁
- * Created by Administrator on 2017/10/12 0012.
- */
- @Component
- public class RedisLockManger {
- private static final Logger LOGGER = LoggerFactory.getLogger(RedisLockManger.class);
- //设置3秒过期
- private static final int DEFAULT_SINGLE_EXPIRE_TIME = 3;
- // private static final int DEFAULT_BATCH_EXPIRE_TIME = 6;
- //static的变量无法注解
- @Autowired
- private JedisCluster jc;
- private static RedisLockManger lockManger;
- public RedisLockManger() {
- }
- @PostConstruct
- private void init() {
- lockManger = this;
- lockManger.jc = this.jc;
- }
- /**
- * 获取锁 如果锁可用 立即返回true, 否则立即返回false,作为非阻塞式锁使用
- * @param key
- * @return
- */
- public boolean tryLock(String key/* , String value*/) {
- try {
- return tryLock(key, key, 0L, null);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return false;
- }
- /**
- * 锁在给定的等待时间内空闲,则获取锁成功 返回true, 否则返回false,作为阻塞式锁使用
- * @param key 锁键
- * @param value 被谁锁定
- * @param timeout 尝试获取锁时长,建议传递500,结合实践单位,则可表示500毫秒
- * @param unit,建议传递TimeUnit.MILLISECONDS
- * @return
- * @throws InterruptedException
- */
- public boolean tryLock(String key , String value , long timeout , TimeUnit unit) throws InterruptedException {
- //纳秒
- long begin = System.nanoTime();
- do {
- //LOGGER.debug("{}尝试获得{}的锁.", value, key);
- Long i = lockManger.jc.setnx(key, value);
- if (i == 1) {
- lockManger.jc.expire(key, DEFAULT_SINGLE_EXPIRE_TIME);
- LOGGER.debug(value + "-成功获取{}的锁,设置锁过期时间为{}秒 ", key, DEFAULT_SINGLE_EXPIRE_TIME);
- return true;
- } else {
- // 存在锁 ,但可能获取不到,原因是获取的一刹那间
- // String desc = lockManger.jc.get(key);
- // LOGGER.error("{}正被{}锁定.", key, desc);
- } if (timeout == 0) {
- break;
- }
- //在其睡眠的期间,锁可能被解,也可能又被他人占用,但会尝试继续获取锁直到指定的时间
- Thread.sleep(100);
- } while ((System.nanoTime() - begin) < unit.toNanos(timeout));
- //因超时没有获得锁
- return false;
- }
- /**
- * 释放单个锁
- * @param key 锁键
- */
- public void unLock(String key/*, String value*/) {
- lockManger.jc.del(key);
- LOGGER.debug("{}锁被{}释放 .", key, key);
- }
- }
2. 使用示例:
首先在需要加锁的地方注入分布式锁管理器:
- @Autowired
- private RedisLockManger redisLock;
然后调用即可,如:
- if (redisLock.tryLock("statusCheck")) { //此处代码是锁上的
- logger.debug("-----------------------:10秒执行一次!每次只有一个程序运行");
- //释放锁,正常情况下,此处代码要注释掉,以免锁被释放,需要释放时可以根据自己逻辑的需要
- //redisLock.unLock("statusCheck");
- }
首先注入需要的
基于redis集群实现的分布式锁,可用于秒杀,定时器。的更多相关文章
- 基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有測试代码(何志雄)
转载请标明出处. 在分布式系统中,常常会出现须要竞争同一资源的情况,本代码基于redis3.0.1+jedis2.7.1实现了分布式锁. redis集群的搭建,请见我的另外一篇文章:<>& ...
- 分布式ID系列(4)——Redis集群实现的分布式ID适合做分布式ID吗
首先是项目地址: https://github.com/maqiankun/distributed-id-redis-generator 关于Redis集群生成分布式ID,这里要先了解redis使用l ...
- springcloud微服务基于redis集群的单点登录
springcloud微服务基于redis集群的单点登录 yls 2019-9-23 简介 本文介绍微服务架构中如何实现单点登录功能 创建三个服务: 操作redis集群的服务,用于多个服务之间共享数据 ...
- 【spring boot】【redis】spring boot基于redis的LUA脚本 实现分布式锁
spring boot基于redis的LUA脚本 实现分布式锁[都是基于redis单点下] 一.spring boot 1.5.X 基于redis 的 lua脚本实现分布式锁 1.pom.xml &l ...
- 集群多JVM分布式锁实现
基于数据库表乐观锁 (基本废弃) 要实现分布式锁,最简单的⽅方式可能就是直接创建⼀一张锁表,然后通过操作该表中的数据来实现了了. 当我们要锁住某个⽅法或资源时,我们就在该表中增加一条记录,想要释放锁的 ...
- Redis集群模式之分布式集群模式
前言 Redis集群模式主要有2种: 主从集群 分布式集群. 前者主要是为了高可用或是读写分离,后者为了更好的存储数据,负载均衡. 本文主要讲解主从集群.本章主要讲解后一半部分,Redis集群. 与本 ...
- 【连载】redis库存操作,分布式锁的四种实现方式[四]--基于Redis lua脚本机制实现分布式锁
一.redis lua介绍 Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题.Redis 为这样的用户场景提供了 lua 脚本支持,用户可以向 ...
- java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购
此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...
- Couchbase集群和Redis集群解析
Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...
随机推荐
- stopManagedWebLogic.sh强制关闭Managed Server
Adding force shutdown of managed server in weblogic. ----------------------------------------------- ...
- Cents os 7下如何安装bzip2
# Cents os 7下如何安装bzip2 ### 安装```yum search bzip2 //查询安装包 yum -y install bzip2.x86_64 ``` ### 原因---- ...
- Oracle用户密码过期的处理方法
受影响版本:Oracle11g以上版本. 导致密码消失的原因:Oracle 11g中默认的DEFAULT概要文件中口令有效期PASSWORD_LIFE_TIME默认值为180天. 当以客户端登 ...
- 2. 知识图谱-命名实体识别(NER)详解
1. 通俗易懂解释知识图谱(Knowledge Graph) 2. 知识图谱-命名实体识别(NER)详解 3. 哈工大LTP解析 1. 前言 在解了知识图谱的全貌之后,我们现在慢慢的开始深入的学习知识 ...
- 基于jQuery实现的腾讯互动娱乐网站特效
分享一款基于jQuery实现的腾讯互动娱乐网站特效.腾讯互动娱乐网站jQuery特效是一款右侧带伸缩选项卡,支持鼠标滚轮滚动切换特效代码.效果图如下: 在线预览 源码下载 实现的代码. html代 ...
- wcf中的Message类
客户端->服务端—>客户端 客户端代码: using (new OperationContextScope(client.InnerChannel)) { ...
- [转]基于BootStrap 的城市三级联动
原文地址:https://blog.csdn.net/peiyuanxin/article/details/51992384 HTML代码部分 <div class="form- ...
- Swift is Open Source 博客note
Swift is Open Sourcehtml, body {overflow-x: initial !important;}html { font-size: 14px; } body { mar ...
- composer安装与应用
操作环境:centos 6.5+32bit 1. 建立项目目录 mkdir test cd test 2. 在当前目录下安装: $ curl -sS https://getcomposer.org/i ...
- Domain应用之 根据某个Many2one的对象的 X2many对象 过滤
如果两者都是many2one类型的对象,过滤非常简单,在xml中添加domain过滤即可,比如 国家.省市之间的联动关系. 如果想要根据某个对象的X2many类型的字段进行过滤该如何去做呢? 答案是利 ...