要解决这个问题,如何在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 上执行一次。
有人可以帮忙吗?
您所做的是确保任务不会并行执行,但我希望您的quartz配置使用RAMJobStore,因此Quartz的每个实例都充当单个实体,因此每个实例都将运行该作业并且它只会等待锁定。
你能做的是:
lock.acquire
,超时时间很短 - 要么成功,要么失败。对于快速任务来说它不是很可靠,但是如果任务足够长,您可以获得它可以正常工作的参数。