package com.myzmds.ecp.core.standard.mq.delayed; import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; /** * @类名称 RedisDelayeTimeRound.java * @类描述 <pre>redis延时消息时间轮</pre> * @作者 庄梦蝶殇 [email protected] * @创建时间 2019年12月25日 下午3:22:29 * @版本 1.0.0 * * @修改记录 * <pre> * 版本 修改人 修改日期 修改内容描述 * ---------------------------------------------- * 1.0.0 庄梦蝶殇 2019年12月25日 * ---------------------------------------------- * </pre> */ public class RedisDelayeTimeRound extends TimeRound<String> { @Autowired public RedisTemplate<String, String> redisTemplate; @Autowired RedisDelayMsgServiceImpl msgQueue; public Integer queueSize = 20; public RedisDelayeTimeRound(int queueSize) { super(3600); } /** * @方法名称 lockLoad * @功能描述 <pre>需要一小时加载一次</pre> */ @Override public void lockLoad() { // 一小时的数据量 long start = System.currentTimeMillis(); long end = start + 3600000; Set<TypedTuple<String>> set = new HashSet<>(); for (int i = 0; i < queueSize; i++) { set.addAll(redisTemplate.boundZSetOps(RedisDelayMsgServiceImpl.TOPIC_DELAYE + i).rangeByScoreWithScores(start, end)); } set.stream().collect(Collectors.groupingBy(TypedTuple::getScore)).entrySet().stream().forEach(item -> { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(item.getKey().longValue()); bucketBuffer[calendar.get(Calendar.SECOND)] = item.getValue().stream().map(TypedTuple::getValue).collect(Collectors.toList()); }); } public void invoke() { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.SECOND, currentPos); calendar.set(Calendar.MILLISECOND, 0); for (int i = 0; i < queueSize; i++) { redisTemplate.boundZSetOps(RedisDelayMsgServiceImpl.TOPIC_DELAYE + i).removeRangeByScore(calendar.getTimeInMillis() - 100, calendar.getTimeInMillis()); } List<String> bucket = bucketBuffer[currentPos]; redisTemplate.boundSetOps(RedisDelayMsgServiceImpl.TOPIC_READY).add(bucket.toArray(new String[bucket.size()])); } /** * @方法名称 addTask * @功能描述 <pre>增加时间桶任务</pre> * @param task 时间桶任务 */ public void addTask(Message task) { msgQueue.push(task); } }