把执行时间作为分数,存到zset中。
定时任务,分数倒序取出第一个,小于当前时间,说明消息可以执行了
发送延时消息服务
public Object publishDelayedMsg() {
OrderDTO dto = new OrderDTO();
dto.setId(1);
dto.setCreateTime(new Date());
dto.setMoney("12.34");
dto.setOrderNo("orderNo1");
String s = JSON.toJSONString(dto);
long executeTime = System.currentTimeMillis() + 60000L;
ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
zSetOperations.add(RedisConstant.MQ_ZSET, s, executeTime);
Long size = zSetOperations.size(RedisConstant.MQ_ZSET);
Set<String> set = new HashSet<>();
if (size != null && size > 0) {
set = zSetOperations.range(RedisConstant.MQ_ZSET, 0, size - 1);
}
return set;
}
controller
//http://localhost:9040/redisZset/publishDelayedMsg
@GetMapping("publishDelayedMsg")
public Object publishDelayedMsg() {
return redisService.publishDelayedMsg();
}
消费消息服务
定时任务
@TaskLock(RedisConstant.CONSUME_REDIS_ZSET_TASK)
@Scheduled(cron = "0/10 * * * * ?")
public void consumeMqZset() {
redisService.consumeMqZset();
}
消费消息
public void consumeMqZset() {
ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
Set<ZSetOperations.TypedTuple<String>> typedTuples = zSetOperations.reverseRangeByScoreWithScores(RedisConstant.MQ_ZSET, 0, System.currentTimeMillis(), 0, 1);
if (typedTuples == null || typedTuples.isEmpty()) {
return;
}
ZSetOperations.TypedTuple<String> typedTuple = typedTuples.iterator().next();
Double score = typedTuple.getScore();
if (score == null) {
return;
}
long l = score.longValue();
if (l > System.currentTimeMillis()) {
return;
}
String value = typedTuple.getValue();
OrderDTO dto = JSON.parseObject(value, OrderDTO.class);
System.out.println(dto);
zSetOperations.remove(RedisConstant.MQ_ZSET, value);
}
消费完消息后,删除消息
https://github.com/mingwulipo/cloud-demo.git