借助redis实现分布式定时任务锁
场景说明:当前系统是分布式的,工程中有定时任务,要求同一时间只有一个任务出发执行,也不要都在一个部署的服务执行。
技术引用:redisson 3.17.7、spring boot 2.2.5
核心代码:
配置类
package com.example.demo;import org.redisson.Redisson;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;@Component
public class RedissionConfig {private static final String RAtomicName = "genId_";private static Config config = new Config();private static RedissonClient redisson = null;public static void init() {try {//静态方法先加载,所以使用这种方式获取配置文件的内容ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class );String hosts = run.getBean(Environment.class).getProperty("spring.redis.cluster.nodes");String password = run.getBean(Environment.class).getProperty("spring.redis.password");String[] host = hosts.split(",");StringBuilder hostStr = new StringBuilder();for (String s : host) {hostStr.append("redis://" + s).append(";");}config.useClusterServers().setPassword(password).setScanInterval(200000)//设置集群状态扫描间隔.setMasterConnectionPoolSize(10000)//设置对于master节点的连接池中连接数最大为10000.setSlaveConnectionPoolSize(10000)//设置对于slave节点的连接池中连接数最大为500.setIdleConnectionTimeout(10000)//如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。.setConnectTimeout(30000)//同任何节点建立连接时的等待超时。时间单位是毫秒。.setTimeout(3000)//等待节点回复命令的时间。该时间从命令发送成功时开始计时。.setRetryInterval(3000)//当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。.addNodeAddress(hostStr.toString().split(";"));redisson = Redisson.create(config);RAtomicLong atomicLong = redisson.getAtomicLong(RAtomicName);atomicLong.set(0);//自增设置为从0开始} catch (Exception e) {e.printStackTrace();}}public static RedissonClient getRedisson() {if (redisson == null) {RedissionConfig.init(); //初始化}return redisson;}
}
加锁工具类
package com.example.demo;import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Component
public class RedissonLock {private static final Logger LOGGER = LoggerFactory.getLogger(RedissonLock.class);private static RedissonClient redissonClient = RedissionConfig.getRedisson();//加锁public boolean lock(String lockName,long second ) {RLock myLock = redissonClient.getLock(lockName);//lock提供带timeout参数,timeout结束强制解锁,防止死锁
// myLock.lock(30, TimeUnit.SECONDS);// 1. 最常见的使用方法//lock.lock();// 2. 支持过期解锁功能,10秒以后自动解锁, 无需调用unlock方法手动解锁+//lock.lock(10, TimeUnit.SECONDS);// 3. 尝试加锁,最多等待3秒,上锁以后10秒自动解锁try {boolean res = myLock.tryLock(1, second, TimeUnit.SECONDS);System.out.println(res);return res;} catch (InterruptedException e) {e.printStackTrace();}System.err.println("======lock======" + Thread.currentThread().getName());return false;}public void lock(String lockName) {lock(lockName , 30);}//锁是否存在public boolean isLock(String lockName) {String key = lockName;RLock myLock = redissonClient.getLock(key);return myLock.isLocked();}//解锁public void unLock(String lockName) {String key = lockName;RLock myLock = redissonClient.getLock(key);myLock.unlock();System.err.println("======unlock======" + Thread.currentThread().getName());}
}
yml配置
server:port: 8081
spring:redis:database: 0cluster:nodes: 192.168.56.201:6379,192.168.56.202:6379,192.168.56.203:6379password: 123456timeout: 30slettuce:pool:max-wait: -1max-active: 300max-idle: 100min-idle: 20
测试
package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;@SpringBootApplication
@EnableScheduling
public class DemoApplication {@AutowiredRedissonLock lock;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Scheduled(cron = "0 40 11 * * ?")public void scheduled1() throws InterruptedException {for (int i = 0; i < 5; i++) {String key ="lo"+i;if (lock.isLock(key)){continue;}boolean lock = this.lock.lock(key, 3);if (!lock){continue;}System.out.println("=====>>>>>使用cron "+System.currentTimeMillis());System.out.println(key);Thread.sleep(1000);this.lock.unLock(key);}}@Scheduled(cron = "0 42 11 * * ?")public void scheduled2() throws InterruptedException {for (int i = 0; i < 5; i++) {String key ="lo"+i;if (lock.isLock(key)){continue;}//判断尝试加锁是否成功boolean lock = this.lock.lock(key, 3);if (!lock){continue;}System.out.println("=====>>>>>使用cron "+System.currentTimeMillis());System.out.println(key);Thread.sleep(1000);this.lock.unLock(key);}}
}
借助redis实现分布式定时任务锁相关推荐
- Spring Cloud Alibaba微服务项目中集成Redis实现分布式事务锁实践
引言 我们知道同一个进程里面为了解决资源共享而不出现高并发的问题可以通过高并发编程解决,通过给变量添加volatile关键字实现线程间变量可见:通过synchronized关键字修饰代码块.对象或者方 ...
- spring boot基于redis的分布式定时任务
第一步. 自动配置类 主启动类添加:@EnableScheduling //开启定时任务 aop和redis POM添加: <!--redis驱动--><dependency> ...
- SpringBoot(46) 整合ShedLock实现分布式定时任务(redis版)
文章目录 一.前言 二.SpringBoot整合ShedLock 1.`pom.xml`中引入依赖 2.Shedlock配置类 3.测试数据定时任务 三.本文案例demo源码 一.前言 本文将基于sp ...
- 采用docker部署3台Redis分布式红锁实例
采用docker部署3台Redis分布式红锁实例 docker run -p 6381:6379 --name redis-master-1 -d redis:5.0.7 docker run -p ...
- SpringBoot2.x整合轻量级分布式定时任务ShedLock3.x的使用详解
目录 前言 SpringBoot2.x整合轻量级分布式定时任务ShedLock3.x的使用详解 一.关于ShedLock 二.ShedLock的三个核心组件 三.ShedLock使用三步走 四.Spr ...
- 基于Redis实现分布式锁,避免重复执行定时任务
Spring提供了定时任务的功能,但是在多个实例的集群中,会出现定时任务重复执行多次的情况. 使用Qutaz框架自带的分布式定时任务可以很好的解决这个问题,但是讲道理功能有些过于强大,对于需求不高,乃 ...
- 【redis】分布式锁实现,与分布式定时任务
如果你还不知道redis的基本命令与基本使用方法,请看 [redis]redis基础命令学习集合 写在前面 redis辣么多数据结构,这么多命令,具体一点,都可以应用在什么场景呢?用来解决什么具体的问 ...
- 使用redis分布式锁+lua脚本实现分布式定时任务控制demo
2019独角兽企业重金招聘Python工程师标准>>> 分布式系统经常要遇到定时任务执行的问题,不能重复执行,但很多时候又不能统一到一个微服务里面,因为这样就失去了微服务的意义.由于 ...
- Redis的分布式锁详解
一.什么是分布式锁: 1.什么是分布式锁: 分布式锁,即分布式系统中的锁.在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题.与单体应用不同 ...
最新文章
- 很实用的Python运行提速方法
- codeforces 7.22 E Permutation Shift
- Java基础 -- 复用类(组合和继承)
- redis的安装过程基本配置及遇到问题的解决
- 动感灯箱制作流程培训_从事广告行业20年老师傅,揭秘广告牌类型和制作工艺流程 !...
- 动态规划——基本思想
- 整套的操作体系:三点看股法
- Python安装xlrd和xlwt的步骤以及使用报错的解决方法
- [MAC] 6 个好用小技巧
- 当启动文档转换负载平衡器服务时出现如下问题The system cannot find the file specified的解决方案...
- FPGA数字信号处理(十)ASK调制技术
- 给神经网络加入先验知识!
- 联盛德 HLK-W806 (十三): 运行FatFs读写FAT和exFat格式的SD卡/TF卡
- 人类一败涂地怎么正在连接服务器,人类一败涂地联机显示正在连接服务器解决办法...
- git重新设置用户名密码
- python3教程合集
- 45条Win XP必知实用技巧
- 发布/上传Jar包到Maven中央仓库 - 史上最详细
- 旭日X3派AI推理(YOLOv5测试)
- 庞皓计量经济学第四版_庞皓计量经济学第4版配套题库