You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.8 KiB

/*
package com.example.demo.Util;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.concurrent.*;
@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, Object> redisTemplate;
// 线程池用于处理延迟消息
private ExecutorService delayMessageExecutor;
// 延迟消息处理线程数
private static final int DELAY_THREAD_POOL_SIZE = 4;
// 延迟队列轮询间隔(毫秒)
private static final long DELAY_QUEUE_POLL_INTERVAL = 1000L;
@PostConstruct
public void init() {
// 初始化线程池
delayMessageExecutor = Executors.newFixedThreadPool(DELAY_THREAD_POOL_SIZE);
}
*/
/**
* 发送消息到队列
* @param queueName 队列名称
* @param message 消息内容
*//*
public void sendMessage(String queueName, Object message) {
redisTemplate.opsForList().rightPush(queueName, message);
}
*/
/**
* 阻塞获取消息(优化版,增加重试机制)
* @param queueName 队列名称
* @param timeout 超时时间(秒)
* @return 消息内容
*//*
public Object blockingGetMessage(String queueName, long timeout) {
// 分段获取,避免长时间阻塞
long endTime = System.currentTimeMillis() + timeout * 1000;
while (System.currentTimeMillis() < endTime) {
Object message = redisTemplate.opsForList().leftPop(queueName, 1, TimeUnit.SECONDS);
if (message != null) {
return message;
}
}
return null;
}
*/
/**
* 非阻塞获取消息
* @param queueName 队列名称
* @return 消息内容
*//*
public Object getMessage(String queueName) {
return redisTemplate.opsForList().leftPop(queueName);
}
*/
/**
* 获取队列长度
* @param queueName 队列名称
* @return 队列长度
*//*
public Long getQueueSize(String queueName) {
return redisTemplate.opsForList().size(queueName);
}
*/
/**
* 发送延迟消息(优化版)
* @param queueName 队列名称
* @param message 消息内容
* @param delay 延迟时间(秒)
*//*
public void sendDelayMessage(String queueName, Object message, long delay) {
String delayQueueKey = getDelayQueueKey(queueName);
String messageId = generateMessageId();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) {
connection.openPipeline();
// 直接存储消息内容到ZSet的value中
connection.zAdd(
delayQueueKey.getBytes(),
System.currentTimeMillis() + delay * 1000,
serializeMessage(messageId, message)
);
connection.closePipeline();
return null;
}
});
}
*/
/**
* 启动延迟消息处理任务
*//*
@Scheduled(fixedRate = DELAY_QUEUE_POLL_INTERVAL)
public void processDelayMessages() {
Set<String> delayQueues = redisTemplate.keys("delay:*");
if (delayQueues != null) {
for (String delayQueue : delayQueues) {
delayMessageExecutor.execute(() -> {
String queueName = delayQueue.substring(6); // 去掉"delay:"前缀
processSingleDelayQueue(queueName);
});
}
}
}
*/
/**
* 处理单个延迟队列
*//*
private void processSingleDelayQueue(String queueName) {
String delayQueueKey = getDelayQueueKey(queueName);
long now = System.currentTimeMillis();
// 获取所有已到期的消息
Set<ZSetOperations.TypedTuple<Object>> messages = redisTemplate.opsForZSet()
.rangeByScoreWithScores(delayQueueKey, 0, now);
if (messages != null && !messages.isEmpty()) {
for (ZSetOperations.TypedTuple<Object> tuple : messages) {
Object messageWithId = tuple.getValue();
if (messageWithId != null) {
// 反序列化消息
Object message = deserializeMessage(messageWithId.toString());
// 发送到实际队列
sendMessage(queueName, message);
// 从延迟队列中移除
redisTemplate.opsForZSet().remove(delayQueueKey, messageWithId);
}
}
}
}
// 生成消息ID
private String generateMessageId() {
return java.util.UUID.randomUUID().toString();
}
// 获取延迟队列key
private String getDelayQueueKey(String queueName) {
return "delay:" + queueName;
}
// 序列化消息(可根据实际需求实现)
private byte[] serializeMessage(String messageId, Object message) {
// 这里简单实现,实际项目中可以使用JSON序列化等
return (messageId + ":" + message.toString()).getBytes();
}
// 反序列化消息(可根据实际需求实现)
private Object deserializeMessage(String serialized) {
// 简单实现,根据实际序列化方式调整
int separatorIndex = serialized.indexOf(':');
if (separatorIndex > 0) {
return serialized.substring(separatorIndex + 1);
}
return serialized;
}
}*/