Springboot 定时任务分布式下幂等性解决方案

 更新时间:2023年07月05日 09:51:36   作者:lovoo  
这篇文章主要介绍了Springboot定时任务分布式下幂等性如何解决,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、概述:

在分布式环境下,定时任务的幂等性问题需要考虑多个节点之间的数据一致性和事务处理。

一种解决方法是使用分布式锁来保证同一时间只有一个节点能够执行该任务。具体实现可以使用Redis或Zookeeper等分布式协调工具提供的分布式锁功能。

另一种解决方法是使用消息队列来保证任务的幂等性。当一个节点执行任务时,先将任务发送到消息队列中,然后等待其他节点确认任务已经执行完毕后再进行后续操作。如果有节点出现故障或者网络异常导致任务未能成功执行,则可以重新发送任务并等待其他节点确认。

二、示例

如下图,有三台机器同时启动定时任务,将数据保存到Redis中,如何保证数据的幂等性?

在这里插入图片描述

解决方法–Redission分布式锁:

  • 在启动定时任务时,获取分布式锁,保证只有一个线程进入
  • 在获取锁之后,锁定10秒
  • 然后执行业务
  • 业务执行完成后,释放分布式锁
@Scheduled(cron = "*/10 * * * * ? ")    
public void uploadSeckillSkuLatest3Days() {
    // 重复上架无需处理
    log.info("上架秒杀的商品...");
    // 分布式锁(幂等性)
    RLock lock = redissonClient.getLock(SeckillConstant.UPLOAD_LOCK);
    try {
        lock.lock(10, TimeUnit.SECONDS);
        // 上架最近三天需要秒杀的商品
        seckillService.uploadSeckillSkuLatest3Days();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

上架商品时,判断redis是否有该商品,没有才上架

 Boolean hasKey = redisTemplate.hasKey(key);
 if (!hasKey) {
 }

全部代码

private void saveSessionInfos(List<SeckillSessionWithSkusTO> sessions) {
        if (!CollectionUtils.isEmpty(sessions)) {
            sessions.stream().forEach(session -> {
                // 1.遍历场次
                long startTime = session.getStartTime().getTime();// 场次开始时间戳
                long endTime = session.getEndTime().getTime();// 场次结束时间戳
                String key = SeckillConstant.SESSION_CACHE_PREFIX + startTime + "_" + endTime;// 场次的key
                // 2.判断场次是否已上架(幂等性)
                Boolean hasKey = redisTemplate.hasKey(key);
                if (!hasKey) {
                    // 未上架
                    // 3.封装场次信息
                    List<String> skuIds = session.getRelationSkus().stream()
                            .map(item -> item.getPromotionSessionId() + "_" + item.getSkuId().toString())
                            .collect(Collectors.toList());// skuId集合
                    // 4.上架
                    redisTemplate.opsForList().leftPushAll(key, skuIds);
                }
            });
        }
    }

到此这篇关于Springboot 定时任务分布式下幂等性如何解决的文章就介绍到这了,更多相关Springboot 幂等性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot中yml文件不生效原因分析及解决

    Springboot中yml文件不生效原因分析及解决

    这篇文章给大家介绍了Springboot中yml文件不生效原因分析及解决方法,通过图文给大家讲解的非常详细,对大家解决问题有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • 详解Maven多模块打包遇到的问题解决方法

    详解Maven多模块打包遇到的问题解决方法

    这篇文章主要介绍了详解Maven多模块打包遇到的问题解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 详解Java执行groovy脚本的两种方式

    详解Java执行groovy脚本的两种方式

    这篇文章主要介绍了Java执行groovy脚本的两种方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 浅谈Spring-cloud 之 sleuth 服务链路跟踪

    浅谈Spring-cloud 之 sleuth 服务链路跟踪

    本篇文章主要介绍了浅谈Spring-cloud 之 sleuth 服务链路跟踪,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • IDEA中打jar包的2种方式(Maven打jar包)

    IDEA中打jar包的2种方式(Maven打jar包)

    这篇文章主要给大家介绍了关于IDEA中打jar包的2种方式,分别是不使用Maven直接打Jar包与使用Maven打jar包的两种方法,需要的朋友可以参考下
    2021-05-05
  • Spring Boot实现异步请求(Servlet 3.0)

    Spring Boot实现异步请求(Servlet 3.0)

    在spring 3.2 及以后版本中增加了对请求的异步处理,这篇文章主要介绍了Spring Boot实现异步请求(Servlet 3.0),感兴趣的小伙伴们可以参考一下。
    2017-04-04
  • java servlet手机app访问接口(二)短信验证

    java servlet手机app访问接口(二)短信验证

    这篇文章主要介绍了java servlet手机app访问接口(二),短信验证,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Java导出oracle表结构实例详解

    Java导出oracle表结构实例详解

    这篇文章主要介绍了 Java导出oracle表结构实例详解的相关资料,需要的朋友可以参考下
    2017-03-03
  • 全局请求添加TraceId轻松看日志

    全局请求添加TraceId轻松看日志

    这篇文章主要为大家介绍了全局请求添加TraceId,更加方便轻松的看日志,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 详解Log4j 日志文件存放位置设置

    详解Log4j 日志文件存放位置设置

    这篇文章主要介绍了详解Log4j 日志文件存放位置设置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08

最新评论