Quartz 定时任务在多台服务器部署时,确保任务不会执行两次,避免业务重复执行的机制主要包括以下几点:
-
数据库锁机制:Quartz 的集群方案是基于单机版本加上一个公共数据库实现的。通过在数据库中配置定时器信息,并以数据库锁的方式确保同一个任务始终只有一个节点在运行。
-
集群架构:三个 Quartz 服务节点共享同一个数据库,如果某一个服务节点失效,那么 Job 会在其他节点上执行。各个 Quartz 服务器都遵守基于数据库锁的调度原则,只有获取了锁才能调度后台任务,从而保证了任务执行的唯一性。
-
DisallowConcurrentExecution 注解:在单个任务类上使用
@DisallowConcurrentExecution
注解可以阻止并发执行多个相同定义的 JobDetail 实例。这意味着,即使有多个 JobDetail 实例,相同定义的 JobDetail 不会并发执行,从而避免了同一个任务被重复执行。 -
持久化支持:Quartz 支持持久化作业,即使在系统重启后也能恢复作业状态,确保任务的连续性和一致性。
-
集群检查间隔:在 Quartz 的配置中,
clusterCheckinInterval
参数用于设置集群节点之间的检查间隔,这有助于维持集群状态的同步和一致性。
通过这些机制,Quartz 能够在多节点环境中有效地管理定时任务的执行,确保任务不会被重复执行,从而避免业务逻辑的重复执行。
Elastic-Job 通过其分布式调度协调特性确保在多节点环境下,定时任务不会被重复执行。以下是几个关键机制来保证这一点:
-
分布式调度协调:Elastic-Job 使用 Zookeeper 作为注册中心,进行统一调度,确保在分布式环境中,任务能够按指定的调度策略执行,并且能够避免同一任务多实例重复执行。
-
作业分片一致性:Elastic-Job 保证同一分片在分布式环境中仅一个执行实例,这是通过在 Zookeeper 中创建临时节点来实现的。当任务开始执行时,Elastic-Job 会在 Zookeeper 上创建对应的分片运行节点,任务结束后删除该节点。这样,即使有多个节点,同一分片也不会被重复处理。
-
失效转移(Failover):如果作业执行过程中服务器宕机,失效转移允许将该次未完成的任务在另一作业节点上补偿执行。Elastic-Job 不会在本次执行过程中进行重新分片,而是等待下次调度之前才开启重新分片流程。
-
幂等机制:开启
monitorExecution = true
能实现分布式作业幂等性,不会在多个作业服务器运行同一个分片。Elastic-Job 在开启幂等机制的情况下,会在分片任务开始时在注册中心 Zookeeper 上创建临时节点,在任务结束后会删除该目录。这样即使有多个节点,相同分片不会被重复处理。 -
弹性扩容缩容:Elastic-Job 支持弹性扩容缩容,将任务拆分为多个任务项后,各个服务器分别执行各自分配到的任务项。一旦有新的服务器加入集群,或现有服务器下线,Elastic-Job 将在保留本次任务执行不变的情况下,下次任务开始前触发任务重分片。
通过上述机制,Elastic-Job 确保了即使在多节点环境下,每个任务分片在同一时间内也只会被一个节点执行,从而避免了业务重复执行的问题。
在Elastic-Job中,数据分片是一个重要的概念,它允许任务在分布式环境下运行,每个任务服务器只运行分配给该服务器的分片。对于您提到的将一万条数据分片成4个分片的情况,Elastic-Job本身并不直接处理数据,而是通过分片策略将分片项分配给各个运行中的作业服务器,开发者需要自行处理分片项与业务数据的对应关系。
具体来说,Elastic-Job中的分片项是指任务被拆分成的多个独立的任务项,每个分片项都有一个唯一的标识符,通常是从0开始的数字,直到分片总数减1。例如,如果设置4个分片,那么分片项标识符就是0、1、2、3。
在数据库操作的场景下,您需要根据分片项来编写查询逻辑,以便每个作业服务器只处理分配给它的数据。例如,如果数据存储在数据库中,并且您希望将数据平均分配给4个分片,您可以使用分片项作为查询条件的一部分。假设您有一张表,其中有一个ID字段,您可以编写如下SQL查询来获取每个分片应该处理的数据:
SELECT * FROM your_table WHERE ID % 4 = sharding_item_id;
其中sharding_item_id
是当前分片项的标识符。这样,每个分片就会处理ID模4等于其分片项标识符的数据。例如,如果一个分片的标识符是0,那么它将处理所有ID为4的倍数的数据;如果标识符是1,它将处理所有ID除以4余1的数据,以此类推。
总结来说,Elastic-Job通过分片策略将任务分配给不同的作业服务器,而具体的数据分片逻辑需要开发者根据分片项来实现,以确保每个作业服务器只处理分配给它的数据。