解决XXLJOB重复执行问题--Redis加锁+注解+AOP

基于Redis加锁+注解+AOP解决JOB重复执行问题

  • 现象
  • 解决方案
    • 自定义注解
    • 定义AOP策略
    • redis 加锁
    • 实践

现象

线上xxljob有时候会遇到同一个任务在调度的时候重复执行,如下图:
在这里插入图片描述

线上JOB服务运行了2个实例,有时候会重复调度到同一个实例,有时候会重复调度到不同实例上,对于Job重复执行会存在很多风险,可以采用Redis加锁的方式来解决。这里用统一的方式提供这个内部功能,其他Job或者从管理页面进来的请求直接执行Job可以都限制住,保证同一时间分布式环境中只有一个实例在运行。

解决方案

自定义注解

首先定义一个自定义注解,将redis加锁需要的参数可以通过注解声明:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JobNoRepete {
String name();
String redisKey();
long expireTime();
TimeUnit timeUnit();
}

定义AOP策略

@Component
@Aspect
@Slf4j
public class JobNoRepeteAop {
@Resourceprivate RedisService redisService;
@Around(value = "@annotation(annotation)", argNames = "pj,annotation")public Object around(ProceedingJoinPoint pj, JobRepetitionDefense annotation) throws Throwable {String name = annotation.name();String redisKey = annotation.redisKey();long expireTime = annotation.expireTime();TimeUnit timeUnit = annotation.timeUnit();log.info("job执行防重开始执行,name={},redisKey={},expireTime={},timeUnit={}",name, redisKey, expireTime, timeUnit);try {return redisService.executeOnlyOnce(redisKey, expireTime, timeUnit, pj::proceed);} finally {log.info("job执行防重执行完成,name={}", name);}}

}

redis 加锁

redis 加锁逻辑,使用spring redis中的StringRedisTemplate:

@Slf4j
@Component
public class RedisService {@Resourceprivate StringRedisTemplate stringRedisTemplate;public <T> T executeOnlyOnce(String redisKey, long expireTime, TimeUnit timeUnit, CustomCallable<T> callable) throws Throwable {if (StrUtil.isBlank(redisKey) || expireTime <= 0 || Objects.isNull(timeUnit) || Objects.isNull(callable)) {throw new IllegalArgumentException("参数错误");}String uuid = UUID.randomUUID().toString();if (!stringRedisTemplate.opsForValue().setIfAbsent(redisKey, uuid, expireTime, timeUnit)) {throw new RuntimeException("任务正在执行,请稍后再试");}//执行逻辑try {return callable.call();} finally {//执行完成主动释放锁try {String oldValue = stringRedisTemplate.opsForValue().get(redisKey);if (Objects.equals(uuid, oldValue)) {stringRedisTemplate.delete(redisKey);}} catch (Exception e) {//释放锁失败,等待expireTime后自动释放log.error("释放锁异常", e);}}}
}
public interface CustomCallable<V> {V call() throws Throwable;
}

实践

对于适用的场景就可以直接使用注解的方式进行声明,例如:

@Service
@Slf4j
public class testService {
private static final int EXPIRE_HOURS = 24;
@JobNoRepete(name = "测试redis", redisKey = Constant.JOB_LOCK_TO_REDIS,expireTime = EXPIRE_HOURS, timeUnit = TimeUnit.HOURS)public void test(LocalDate localDate) {//内部逻辑}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/114210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

交换机端口灯常亮 端口up状态 服务器设置ip交换机获取不到服务器网卡mac地址 不能通信

环境: 深信服防火墙 8.0.75 AF-2000-FH2130B-SC S6520X-24ST-SI交换机 version 7.1.070, Release 6530P02 问题描述: 交换机一个vlan下有3台服务器,连接端口2、3、4,2和3连接的服务器正常,交换机3端口灯常亮 端口up状态 服务器自动获取不了地址,改为手动设置ip后,交…

Xubuntu16.04系统中安装create_ap创建无线AP

1.背景说明 在Xubuntu16.04系统的设备上安装无线WIFI模块后&#xff0c;想通过设备自身的无线AP&#xff0c;进行和外部设备的连接&#xff0c;需要安装create_ap软件&#xff0c;并设置无线AP的名称和密码&#xff0c;并设置为开机自启动。 create_ap是一个用于在Linux系统上创…

开源贡献难吗?

本文整理自字节跳动 Flink SQL 技术负责人李本超在 CommunityOverCode Asia 2023 上的 Keynote 演讲&#xff0c;李本超根据自己在开源社区的贡献经历&#xff0c;基于他在贡献开源社区过程中的一些小故事和思考&#xff0c;如何克服困难&#xff0c;在开源社区取得突破&#x…

BetaFlight飞控AOCODAF435V2MPU6500固件编译

BetaFlight飞控AOCODAF435V2MPU6500固件编译 1. 源由2. 准备2.1 板子2.2 代码2.3 工具 3. 配置修改4. 编译4.1 获取代码4.2 获取配置4.3 编译固件4.4 DFU烧录4.5 版本核对 5. 总结 1. 源由 刚拿到一块Aocoda F405V2 (MPU6500) AT32F435飞控板(替换主控芯片)。 Aocoda-RC F40…

金融机器学习方法:K-均值算法

目录 1.算法介绍 2.算法原理 3.python实现示例 1.算法介绍 K均值聚类算法是机器学习和数据分析中常用的无监督学习方法之一&#xff0c;主要用于数据的分类。它的目标是将数据划分为几个独特的、互不重叠的子集或“集群”&#xff0c;以使得同一集群内的数据点彼此相似&…

tomcat 服务器

tomcat 服务器 tomcat: 是一个开源的web应用服务器。区别nginx&#xff0c;nginx主要处理静态页面&#xff0c;那么动态请求&#xff08;连接数据库&#xff0c;动态页面&#xff09;并不是nginx的长处&#xff0c;动态的请求会交给tomcat进行处理。 nginx-----转发动态请求-…

【5G PHY】5G SS/PBCH块介绍(一)

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

使用crul库和R语言的下载器程序

以下是一个使用crul库和R语言的下载器程序&#xff0c;用于从下载音频。此程序使用了jshk.com.cn/get_proxy的代码。 // 导入必要的库 import ("fmt""github.com/cjlapa/crul""io""net/http""net/url""os" )// 主…

在 Python 中使用 Pillow 进行图像处理【3/4】

第三部分 一、腐蚀和膨胀 您可以查看名为 的图像文件dot_and_hole.jpg&#xff0c;您可以从本教程链接的存储库中下载该文件&#xff1a; 该二值图像的左侧显示黑色背景上的白点&#xff0c;而右侧显示纯白色部分中的黑洞。 侵蚀是从图像边界去除白色像素的过程。您可以通过使用…

运算符重载的三种实现方法

一、重载为一般函数 格式&#xff1a;返回类型 operator 运算符(参数列表) struct Complex{//定义一个复数结构&#xff1a;包括实部与虚部两部分 double real;//实部 double imag;//虚部 }; Complex operator(Complex c1,Complex c2){//对加法运算的重载&#xff1a;将运算符…

vue重修之路由【上】

文章目录 单页应用程序: SPA - Single Page Application路由简介Vue Reouter简介VueRouter的使用&#xff08;52&#xff09;组件的存放目录问题组件分类存放目录 路由的封装抽离 单页应用程序: SPA - Single Page Application 单页面应用(SPA): 所有功能在 一个html页面 上 单…

python调用astra进行人脸检测(使用CascadeClassifier)

1、简述 方法&#xff1a;使用opecv中&#xff0c;CascadeClassifier 级联分类器实现人脸检测&#xff0c;CascadeClassifier就是opencv下objdetect模块中用来做目标检测的级联分类器的一个类&#xff0c;它可以帮助我们检测例如车牌、眼睛、人脸等物体。它的大概原理就是判别…

JS类的继承和实现原理详解

一&#xff1a;前言 各位小伙伴在日常开发中&#xff0c;相信一定遇到过Class这种写法。这代表在JS中创建了一个类&#xff0c;并且可以通过这个类去 new 出一个新的对象。其实在JS中&#xff0c;这个类和java中的类是没有区别的&#xff0c;同样具有属性&#xff0c;方法&…

前端多媒体处理工具——ffmpeg的使用

写在前面 在前端领域&#xff0c;FFmpeg 是一个非常有用的工具&#xff0c;它提供了多种媒体格式的封装和解封装&#xff0c;包括多种音视频编码、多种协议的流媒体、多种色彩格式转换、多种采样率转换、多种码率切换等。可以在多种操作系统安装使用。 安装 下载FFmpeg 在网…

深入探讨 Golang 中的追加操作

通过实际示例探索 Golang 中的追加操作 简介 在 Golang 编程领域&#xff0c;append 操作是一种多才多艺的工具&#xff0c;使开发人员能够动态扩展切片、数组、文件和字符串。在这篇正式的博客文章中&#xff0c;我们将踏上一段旅程&#xff0c;深入探讨在 Golang 中进行追加…

【VSCode】解决Open in browser无效

问题描述&#xff1a; 在VSCode中无论是点击右键&#xff0c;选择在默认浏览器中打开&#xff0c;还是按快捷键alt b都没有反应。 解决办法&#xff1a; 右击文件 --> 在文件资源管理器中显示 右击文件&#xff0c;选择属性 点击更改 选择用默认浏览器打开 最后 此时…

音乐制作软件 Studio One 6 mac中文版软件特点

Studio One mac是一款专业的音乐制作软件&#xff0c;该软件提供了全面的音频编辑和混音功能&#xff0c;包括录制、编曲、合成、采样等多种工具&#xff0c;可用于制作各种类型的音乐&#xff0c;如流行音乐、电子音乐、摇滚乐等。 Studio One mac软件特点 1. 直观易用的界面&…

Defender Antivirus占用资源怎么禁止

前言 有时Defender Antivirus 突然磁盘IO很高。导致机器卡得很&#xff0c;开发代码很不方便&#xff0c;本文就介绍如何禁用这个服务。 操作 下载Defender Control https://www.sordum.org/9480/defender-control-v2-1/ 这是当前的最新版本。下载不了就用云盘地址 &#x…

Android Studio(2022.3.1)设置阿里云源-新旧版本

新版本 #settings.gradle.ktsmaven { url uri("https://maven.aliyun.com/repository/public/") }maven { url uri("https://maven.aliyun.com/repository/google/") }maven { url uri("https://maven.aliyun.com/repository/jcenter/") }ma…

git commit报错:running pre-commit hook: lint-staged

报错截图&#xff1a; 报错信息&#xff1a; running pre-commit hook: lint-staged 解决方式&#xff1a; 在项目(vue)的package.json文件中&#xff0c;查找 “husky” 部分&#xff0c;并确认其下的 “pre-commit” 钩子是否正确地引用了 lint-staged。 其中配置示例如下&a…