使用 Zookeeper 进行 Quartz 任务的分布式锁定

问题描述 投票:0回答:1

要解决这个问题,如何在kubernetes集群中的单个pod上运行quartz任务?

我知道 Zookeeper 将是一个不错的选择,以防止在 Spring MVC 应用程序的所有正在运行的 kubernetes pod 上执行quartz 任务(当前在每个 pod 上执行)

我创建了如下配置

@Configuration
public class ZookeeperConfig {

    @Bean
    public CuratorFramework client() {
        CuratorFramework client = CuratorFrameworkFactory.newClient(10.200.XX.XX:2181, new ExponentialBackoffRetry(1000, 3));
        client.start();
        return client;
    }

}

并在我的 QuartzTask 类中自动装配,该类由我的应用程序中可用的每个任务扩展。

@Autowired
CuratorFramework client;

@Override
public final void execute() throws TaskException {
    executionThread = Thread.currentThread();
    String taskName = getTaskName();

    try {
        InterProcessMutex lock = new InterProcessMutex(client, "/admintasks");
        if ( lock.acquire(10000, TimeUnit.MILLISECONDS) )
        {
            try
            {
                LOG.info("Lock acquired, executing task");
                execute(taskName);
            }
            finally
            {
                lock.release();
                LOG.info("Task executed, lock released");
            }
        }
    } catch (Exception e) {
        LOG.error("Exception while trying to execute task with name :: "+taskName, e);
    }
}

我已经测试了我的应用程序并检查任务仍在每个 Pod 上执行。
我需要在任何可用的 pod 上仅执行一次该任务,而不是在所有 pod 上执行一次。

有人可以帮忙吗?

spring kubernetes quartz-scheduler apache-zookeeper
1个回答
0
投票

您所做的是确保任务不会并行执行,但我希望您的quartz配置使用RAMJobStore,因此Quartz的每个实例都充当单个实体,因此每个实例都将运行该作业并且它只会等待锁定。

你能做的是:

  • make
    lock.acquire
    ,超时时间很短 - 要么成功,要么失败。对于快速任务来说它不是很可靠,但是如果任务足够长,您可以获得它可以正常工作的参数。
  • 从所有实例中选择领导者并仅在该实例上运行作业。
© www.soinside.com 2019 - 2024. All rights reserved.