The first tec blog it's about how to set tasks and then task will be executed at
the you time want to happen. so we are going to use redis to handle this . it's a
data structure [ZSetOperations] that can pop the biggest score time out when the
specific time comes. below is core code of implementing task schedule.
class: ConsumeTask
package com.delaytask.demo.consumer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
/**
* @author WEILIN
*/
@Slf4j
@Service
public class ConsumeTask {
private static final String REDIS_KEY_POST = "task:happen:time";
private RedisTemplate redisTemplate;
private ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
public ConsumeTask(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* task: This design must have practical business meaning. It can also be a combination of json
* string + timestamp. timestamp indicates the time when the task is to be executed regularly.
*/
public void produce(String id, Long timestamp) {
log.info("begin add content :{} to redis, the timestamp is :{}", id, timestamp);
ZSetOperations zso = redisTemplate.opsForZSet();
Boolean add;
if (isNumeric(id)) {
add = zso.add(REDIS_KEY_POST, Long.parseLong(id), timestamp);
} else {
add = zso.add(REDIS_KEY_POST, id, timestamp);
}
if (Boolean.TRUE.equals(add)) {
Long size = zso.size(REDIS_KEY_POST);
if (size != null) {
Set> set = zso.rangeWithScores(REDIS_KEY_POST, 0L, size);
if (set != null) {
set.forEach(tuple -> log.info("member:{} score:{}", tuple.getValue(), tuple.getScore()));
}
}
}
log.info("add task to redis is {}", add);
}
/**
* Executes with a fixed delay, which is the delay between the termination of one execution and
* the start of the next.
*/
public void execTaskTake() {
ex.scheduleWithFixedDelay(new Task(), 1, 1, TimeUnit.SECONDS);
}
public class Task implements Runnable {
@Override
public void run() {
long time = System.currentTimeMillis();
ZSetOperations zso = redisTemplate.opsForZSet();
//Take out overdue tasks and take 30 items at a time. adjust them appropriately here.
Set