|
@@ -1,38 +1,22 @@
|
|
package com.backendsys.modules.queue.service.impl;
|
|
package com.backendsys.modules.queue.service.impl;
|
|
|
|
|
|
-import cn.hutool.core.util.ObjectUtil;
|
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
|
-import com.backendsys.modules.queue.entity.Entire;
|
|
|
|
import com.backendsys.modules.queue.service.TaskService;
|
|
import com.backendsys.modules.queue.service.TaskService;
|
|
-import org.springframework.data.domain.Range;
|
|
|
|
-import jakarta.annotation.PostConstruct;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
+import org.springframework.data.domain.Range;
|
|
import org.springframework.data.redis.RedisSystemException;
|
|
import org.springframework.data.redis.RedisSystemException;
|
|
import org.springframework.data.redis.connection.Limit;
|
|
import org.springframework.data.redis.connection.Limit;
|
|
import org.springframework.data.redis.connection.stream.*;
|
|
import org.springframework.data.redis.connection.stream.*;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
-import org.springframework.data.redis.core.StreamOperations;
|
|
|
|
-import org.springframework.data.redis.stream.StreamListener;
|
|
|
|
-import org.springframework.data.redis.stream.StreamMessageListenerContainer;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.time.Duration;
|
|
|
|
-import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
-import java.util.stream.Collectors;
|
|
|
|
-
|
|
|
|
-import static com.volcengine.model.tls.Const.STREAM;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* 任务队列服务
|
|
* 任务队列服务
|
|
*/
|
|
*/
|
|
@Service
|
|
@Service
|
|
-public class TaskServiceImpl implements TaskService, StreamListener<String, MapRecord<String,String,String>> {
|
|
|
|
-
|
|
|
|
- @Autowired
|
|
|
|
- private StreamMessageListenerContainer<String, MapRecord<String,String,String>> container;
|
|
|
|
|
|
+public class TaskServiceImpl_bak implements TaskService {
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
private RedisTemplate redisTemplate;
|
|
private RedisTemplate redisTemplate;
|
|
@@ -49,8 +33,6 @@ public class TaskServiceImpl implements TaskService, StreamListener<String, MapR
|
|
throw e; // 忽略"组已存在"错误
|
|
throw e; // 忽略"组已存在"错误
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- container.receive(Consumer.from(group_name, "my-consumer"),
|
|
|
|
- StreamOffset.create(STREAM, ReadOffset.lastConsumed()), this);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -73,29 +55,47 @@ public class TaskServiceImpl implements TaskService, StreamListener<String, MapR
|
|
public List<MapRecord<String, String, String>> getTaskPaddingList(String stream_key) {
|
|
public List<MapRecord<String, String, String>> getTaskPaddingList(String stream_key) {
|
|
String group_name = stream_key + ":group";
|
|
String group_name = stream_key + ":group";
|
|
|
|
|
|
- // 1. 先确保流和消费者组存在,只需建一次
|
|
|
|
- String stream = "my-stream";
|
|
|
|
- String group = "my-group";
|
|
|
|
- try { // 如果组已存在会抛异常,忽略即可
|
|
|
|
- redisTemplate.opsForStream().createGroup(stream, ReadOffset.latest(), group);
|
|
|
|
- } catch (Exception ignored) {}
|
|
|
|
-
|
|
|
|
- // 2. 轮询消费
|
|
|
|
- StreamOperations<String, String, String> ops = redisTemplate.opsForStream();
|
|
|
|
- while (true) {
|
|
|
|
- List<MapRecord<String, String, String>> list = ops.read(
|
|
|
|
- Consumer.from(group, "sync-consumer"),
|
|
|
|
- StreamReadOptions.empty().count(5).block(Duration.ofSeconds(3)),
|
|
|
|
- StreamOffset.create(stream, ReadOffset.lastConsumed())
|
|
|
|
- );
|
|
|
|
- if (list.isEmpty()) continue;
|
|
|
|
-
|
|
|
|
- for (MapRecord<String, String, String> r : list) {
|
|
|
|
- System.out.println("收到消息 id=" + r.getId() + " body=" + r.getValue());
|
|
|
|
- // 3. ack
|
|
|
|
- redisTemplate.opsForStream().acknowledge(stream, group, r.getId());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+// /* 1. 已读未 ACK 的 Pending 消息 */
|
|
|
|
+// List<MapRecord<String, String, String>> pendingRecords = Collections.emptyList();
|
|
|
|
+// PendingMessagesSummary summary = redisTemplate.opsForStream().pending(stream_key, group_name);
|
|
|
|
+// System.out.println("total = " + summary.getTotalPendingMessages());
|
|
|
|
+// if (summary.getTotalPendingMessages() > 0) {
|
|
|
|
+// Range<String> idRange = summary.getIdRange();
|
|
|
|
+// System.out.println("idRange = " + idRange);
|
|
|
|
+// pendingRecords = redisTemplate.opsForStream().range(stream_key, idRange);
|
|
|
|
+// System.out.println("pendingRecords = " + pendingRecords);
|
|
|
|
+// }
|
|
|
|
+// return pendingRecords;
|
|
|
|
+
|
|
|
|
+ StreamInfo.XInfoGroups groups = redisTemplate.opsForStream().groups(stream_key);
|
|
|
|
+ System.out.println("groups = " + groups);
|
|
|
|
+
|
|
|
|
+ String lastDelivered = groups.stream()
|
|
|
|
+ .filter(g -> group_name.equals(g.groupName()))
|
|
|
|
+ .findFirst()
|
|
|
|
+ .map(StreamInfo.XInfoGroup::lastDeliveredId)
|
|
|
|
+ .orElse("0-0");
|
|
|
|
+ System.out.println("lastDelivered = " + lastDelivered);
|
|
|
|
+
|
|
|
|
+ List<MapRecord<String, String, String>> unread =
|
|
|
|
+ redisTemplate.opsForStream()
|
|
|
|
+ .read(Consumer.from(group_name, "my-consumer"),
|
|
|
|
+ StreamOffset.create(stream_key,
|
|
|
|
+ ReadOffset.from(lastDelivered)));
|
|
|
|
+ System.out.println("unread = " + unread);
|
|
|
|
+ return unread;
|
|
|
|
+
|
|
|
|
+// PendingMessagesSummary summary = redisTemplate.opsForStream().pending(stream_key, group_name);
|
|
|
|
+// Range<String> idRange = summary.getIdRange();
|
|
|
|
+//
|
|
|
|
+// long total = summary.getTotalPendingMessages();
|
|
|
|
+// String minId = idRange.getLowerBound().getValue().orElse(null);
|
|
|
|
+// String maxId = idRange.getUpperBound().getValue().orElse(null);
|
|
|
|
+// System.out.println("total = " + total + ", minId: " + minId + ", maxId: " + maxId);
|
|
|
|
+//
|
|
|
|
+// // 用得到的范围再去查询完整消息
|
|
|
|
+// List<MapRecord<String, String, String>> records = redisTemplate.opsForStream().range(stream_key, idRange);
|
|
|
|
+// return records;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -141,9 +141,6 @@ public class TaskServiceImpl implements TaskService, StreamListener<String, MapR
|
|
redisTemplate.opsForStream().delete(stream_key, task_id);
|
|
redisTemplate.opsForStream().delete(stream_key, task_id);
|
|
}
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
|
- public void onMessage(MapRecord<String, String, String> message) {
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
// // 1. 安全获取消息
|
|
// // 1. 安全获取消息
|