ElasticJob的幂等机制,是指作业分片执行的幂等,他需要做到以下两点:

  • 同一个分片在当前作业实例上不会被重复执行

  • 一个作业分片不能同时在多个作业实例上执行

如何实现幂等

场景模拟:存在任务A执行周期为10s一次。正常情况下任务处理耗时3-5s。但是某一时刻因为数据量突然增大或者因为数据库压力,导致任务耗时超过了10s。在该过程中,任务每10s调度一次,如果没有幂等,那么会存在一个任务同时多个调度的情况,处理相同的数据。

ElasticJob任务执行:com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor#execute()

public final void execute() {
...
// 获取当前作业服务器的分片上下文
ShardingContexts shardingContexts = jobFacade.getShardingContexts();
//是否允许可以发送作业事件
if (shardingContexts.isAllowSendJobEvent()) {
// 发布作业状态追踪事件
jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), State.TASK_STAGING, String.format("Job '%s' execute begin.", jobName));
}
// 在一个调度任务触发后如果上一次任务还未执行,则需要设置该分片状态为mirefire,表示错失了一次任务执行
if (jobFacade.misfireIfRunning(shardingContexts.getShardingItemParameters().keySet())) {
if (shardingContexts.isAllowSendJobEvent()) {
jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), State.TASK_FINISHED, String.format(
"Previous job '%s' - shardingItems '%s' is still running, misfired job will start after previous job completed.", jobName,
shardingContexts.getShardingItemParameters().keySet()));
}
return;
}
...
}

接下来主要看一下jobFacade.misfireIfRunning的实现逻辑

 public boolean misfireIfHasRunningItems(Collection<Integer> items) {
// 没有分片正在运行,返回false,此次任务调度正常进行,否则设置mirefire
if (!this.hasRunningItems(items)) {
return false;
} else {
this.setMisfire(items);
return true;
}
}

如果存在未完成调度的分片,则调用setMisfire(items)方法。如何判断是否有未完成调度的分片呢,看看hasRunningItems(items)的实现逻辑。

public boolean hasRunningItems(Collection<Integer> items) {
LiteJobConfiguration jobConfig = this.configService.load(true);
if (null != jobConfig && jobConfig.isMonitorExecution()) {
Iterator i$ = items.iterator(); int each;
do {
if (!i$.hasNext()) {
return false;
} each = (Integer)i$.next();
} while(!this.jobNodeStorage.isJobNodeExisted(ShardingNode.getRunningNode(each)));
// ShardingNode.getRunningNode(each)
/*
public static String getRunningNode(int item) {
return String.format("sharding/%s/running", item);
}*/
return true;
} else {
return false;
}
}

在Elasticjob开启monitorExecution的机制下,分片任务开始时会创建sharding/分片/running节点,任务完成后删除该节点。所以上述代码中,可以看出来,可以通过是否存在该分片的节点来判断是否有分片正在运行。

同时,调用setMisfire(items)方法的时候,根据代码判断,setMisfire(items)方法为分配给该实例下的所有分片创建持久节点/shading/{item}/misfire节点,只要分配给该实例的任何一分片未执行完毕,则在该实例下的所有分片都增加misfire节点,然后忽略本次任务触发执行,等待任务结束后再执行。

    public void setMisfire(Collection<Integer> items) {
Iterator i$ = items.iterator(); while(i$.hasNext()) {
int each = (Integer)i$.next();
this.jobNodeStorage.createJobNodeIfNeeded(ShardingNode.getMisfireNode(each));
}
// ShardingNode.getMisfireNode(each)
/**
static String getMisfireNode(int item) {
return String.format("sharding/%s/misfire", item);
}
*/ }

在该执行方法中(com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor#execute())

//执行job
execute(shardingContexts, JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER); // 如果存在Misfire节点,则清除该节点
while (jobFacade.isExecuteMisfired(shardingContexts.getShardingItemParameters().keySet())) {
// 清除Misfire节点
jobFacade.clearMisfire(shardingContexts.getShardingItemParameters().keySet());
execute(shardingContexts, JobExecutionEvent.ExecutionSource.MISFIRE);
}

总结:在下一个调度周期到达之后,只要发现这个分片的任何一个分片正在执行,则为该实例分片的所有分片都设置为misfire,等任务执行完毕后,再统一执行下一次任务调度。

Elasticjob执行job幂等的更多相关文章

  1. elastic-job 新手指南

    大多数情况下,定时任务我们一般使用quartz开源框架就能满足应用场景.但如果考虑到健壮性等其它一些因素,就需要自己下点工夫,比如:要避免单点故障,至少得部署2个节点吧,但是部署多个节点,又有其它问题 ...

  2. Elastic-Job快速入门

    1 Elastic-Job快速入门1.1 环境搭建1.1.1.版本要求JDK要求1.7及以上版本Maven要求3.0.4及以上版本zookeeper要求采用3.4.6及以上版本1.1.2.Zookee ...

  3. 进击的Python【第二章】:Python基础(二)

    Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...

  4. 自动化运维工具Ansible详细部署 (转载)

    自动化运维工具Ansible详细部署 标签:ansible 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog. ...

  5. 自动化服务安装部署工具-Ansible

    自动化运维工具Ansible详细部署 ================================================================================= ...

  6. Ansible学习笔记

    一.Ansible简介 Ansible是一种agentless(基于ssh),可实现批量配置.命令执行和控制,基于Python实现的自动化运维工具. 其特性有: ①模块化:通过调用相关模块,完成指定任 ...

  7. 关于QCon2015感想与反思

    QCon2015专场有不少关于架构优化.专项领域调优专题,但能系统性描述产品测试方向只有<携程无线App自动化测试实践>.   (一). 携程的无线App自动化     <携程无线A ...

  8. MongoDB副本集学习(一):概述和环境搭建

    MongoDB副本集概述 以下图片摘自MongoDB官方文档:http://docs.mongodb.org/manual/core/replication-introduction/ Primary ...

  9. python-ansible

    http://sofar.blog.51cto.com/353572/1579894 http://www.aikaiyuan.com/6299.html http://docs.ansible.co ...

  10. 自动化运维工具之ansible

    自动化运维工具之ansible   一,ansible简介 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fab ...

随机推荐

  1. CSS——样式继承

    CSS的样式表继承指的是,特定的CSS属性向下传递到子孙元素.总的来说,一个HTML文档就是一个家族,然后html元素有两个子元素,相当于它的儿子,分别是head和body,然后body和head各自 ...

  2. nginx对称加密算法和非对称加密算法nginx证书配置

    对称加密算法 对称加密性能更好 对称加密: 客户端和服务器之间的通信数据是通过对称加密算法进行加密,对称加密是在加密和解密的过程中使用同一个私钥进行加密和解密,而且加密算法是公开的,所以对称加密中的私 ...

  3. 数据库系列16:MyISAM与InnoDB的索引对比

    相关文章 数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩 ...

  4. win10系统(专业版)实现双网卡链路聚合

    win10系统(专业版)实现双网卡链路聚合 参考: https://learn.microsoft.com/zh-cn/powershell/module/netswitchteam/new-nets ...

  5. 高可用集群MHA方案

    爱奇艺在用的数据库高可用方案 MHA 是目前比较成熟及流行的 MySQL 高可用解决方案,很多互联网公司正是直接使用或者基于 MHA 的架构进行改造实现 MySQL 的高可用. MHA 能在 30 秒 ...

  6. Vue学习:21.mixins混入

    在Vue中,mixins(混入)是一种用于分发Vue组件中可复用功能的灵活机制.它们允许你抽取组件中的共享功能,如数据.计算属性.方法.生命周期钩子等,并将其作为单独的模块复用到多个组件中.这种方式有 ...

  7. 燕千云ITAM:解锁数字化时代下企业竞争新优势

    数字化时代下,企业的IT资产管理(ITAM)尤为关键.企业通过在成长的每个阶段实施有效的IT资产管理策略,以确保资源的最优化利用和风险的有效控制,并在竞争激烈的市场环境中保持优势.然而实际实践中,企业 ...

  8. 在线Bcrypt加密、验证工具

    在线bcrypt加密,bcrypt算法是一种密码哈希算法,它是基于Blowfish加密算法改进的,能够生成安全性很高的哈希值,并且可以通过调整计算时间来提高安全性.本工具支持在线Bcrypt加密及验证 ...

  9. LangChain和Hub的前世今生

    作为LLM(大模型)开发框架的宠儿,LangChain在短短几年内迅速崛起,成为开发者们不可或缺的工具.本文将带你探讨LangChain和LangChainHub的发展历程. 1. LLM开发框架的宠 ...

  10. 算法金 | 没有思考过 Embedding,不足以谈 AI

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 抱个拳,送个礼 在当今的人工智能(AI)领域,Embedding 是一个不可或缺的概念 ...