解决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后,交…

力扣labuladong——一刷day01

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、21. 合并两个有序链表二、力扣86. 分隔链表三、力扣23. 合并 K 个升序链表四、力扣删除链表的倒数第 N 个结点 前言 一、21. 合并两个有序链表 /*** Defin…

微信小程序 onLoad和onShow的区别

在微信小程序中&#xff0c;onLoad() 和 onShow() 是两个常用的生命周期函数&#xff0c;用于监听页面的加载和显示事件。这两个函数的区别如下&#xff1a; 触发时机 onLoad() 函数只会在页面加载时触发一次&#xff0c;而 onShow() 函数每次页面显示时都会被触发。因此&#…

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

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

Addressable使用指南

1、基础用法就不再赘述了&#xff0c;重要的属性配置&#xff1a; Disable Catalog Update on Startup&#xff1a;禁用时在初始化Addressables的时候自动更新远程的catalog&#xff08;启用后可以通过代码 Addressables.CheckForCatalogUpdates()更新&#xff09; Use…

开源贡献难吗?

本文整理自字节跳动 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;方法&…

使用vue3前端开发的一些知识点

Vue 3 是一种流行的 JavaScript 框架&#xff0c;用于构建用户界面。它是 Vue.js 框架的第三个主要版本&#xff0c;具有许多新特性和性能改进。下面是 Vue 3 的一些常用语法和概念的详细介绍&#xff1a; 创建 Vue 实例&#xff1a; 在 Vue 3 中&#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;选择属性 点击更改 选择用默认浏览器打开 最后 此时…