我希望在我们的项目中将Quartz替换为作业调度程序。我们已经将Redis与集群支持一起用作分布式缓存层,我们认为也许我们也可以使用Redis进行作业调度。有没有人使用Redis在Java中实现作业调度?我搜索但找不到为此目的的图书馆。所以我开始认为这可能不是一个受欢迎的解决方案?
答案 0 :(得分:2)
看看Redisson。它允许使用简单的ScheduledExecutorService api并基于Redis队列来安排和执行任务(使用cron-expression支持)。
这是一个例子。首先使用java.lang.Runnable
接口定义任务。每个任务都可以通过注入的RedissonClient
对象访问Redis实例。
public class RunnableTask implements Runnable {
@RInject
private RedissonClient redissonClient;
@Override
public void run() throws Exception {
RMap<String, Integer> map = redissonClient.getMap("myMap");
Long result = 0;
for (Integer value : map.values()) {
result += value;
}
redissonClient.getTopic("myMapTopic").publish(result);
}
}
将其提交给基于Redis的ExecutorService。
RScheduledExecutorService executorService = redisson.getExecutorService("myExecutor");
ScheduledFuture<?> future = executorService.schedule(new CallableTask(), 10, 20, TimeUnit.MINUTES);
future.get();
// or cancel it
future.cancel(true);
cron表达式的示例:
executorService.schedule(new RunnableTask(), CronSchedule.of("10 0/5 * * * ?"));
executorService.schedule(new RunnableTask(), CronSchedule.dailyAtHourAndMinute(10, 5));
executorService.schedule(new RunnableTask(), CronSchedule.weeklyOnDayAndHourAndMinute(12, 4, Calendar.MONDAY, Calendar.FRIDAY));
所有任务都分布在Redisson nodes。您可以根据需要运行这些节点。
答案 1 :(得分:1)
答案 2 :(得分:1)
我使用带有 Shedlock 和 Redis 的 Spring Task Scheduler 来使计划任务执行可分发。
在我的 XML 配置文件中,我指定了任务调度程序:
<task:scheduler id="myScheduler" pool-size="4"/>
<task:annotation-driven scheduler="myScheduler" />
在 SchedulerLockConfiguration.java
中,我创建了 LockProvider
Spring bean 并设置了 Redis 连接和 Jedis 连接池:
@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "PT10H")
public class SchedulerLockConfiguration {
@Bean
public JedisPool jedisPool() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(100); // The maximum number of connections that are supported by the pool
jedisPoolConfig.setMaxIdle(100); // The maximum number of idle connections in the pool
jedisPoolConfig.setMinIdle(10); // The minimum number of idle connections in the pool
return new JedisPool(
jedisPoolConfig,
Constants.REDIS_HOSTNAME,
Integer.parseInt(Constants.REDIS_PORT),
Integer.parseInt(Constants.REDIS_SESSION_TIMEOUT),
null,
Constants.REDIS_DATABASE_SHEDLOCK);
}
@Bean
public LockProvider lockProvider(JedisPool jedisPool) {
return new JedisLockProvider(jedisPool, "yourRedisNamespace");
}
}
...最后,我在要调度的方法上使用 @Scheduled
和 @SchedulerLock
注释:
@Scheduled(cron = "${my.cron.expression}")
@SchedulerLock(name = "myScheduler", lockAtLeastFor = "PT10M")
public void processDelayedAutomationRules() { ... }
当@Scheduled 作业的 cron 启动时,无论哪个应用程序实例/服务器节点将锁更快地放入 Redis 存储,都会执行它。