分区信息里展示当前分区的有效时间范围

This commit is contained in:
许晓东
2021-12-20 20:29:34 +08:00
parent 0ec3bac6c2
commit 98f33bb2cc
6 changed files with 76 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
# kafka可视化管理平台 # kafka可视化管理平台
一款轻量级的kafka可视化管理平台安装配置快捷、简单易用。 一款轻量级的kafka可视化管理平台安装配置快捷、简单易用。
为了开发的省事,没有多语言支持,只支持中文展示。 为了开发的省事,没有国际化支持,只支持中文展示。
用过rocketmq-console吧前端展示风格跟那个有点类似。 用过rocketmq-console吧前端展示风格跟那个有点类似。
## 安装包下载 ## 安装包下载
以下两种方式2选一直接下载安装包或下载源码手动打包 以下两种方式2选一直接下载安装包或下载源码手动打包

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 492 KiB

View File

@@ -10,7 +10,7 @@
</parent> </parent>
<groupId>com.xuxd</groupId> <groupId>com.xuxd</groupId>
<artifactId>kafka-console-ui</artifactId> <artifactId>kafka-console-ui</artifactId>
<version>1.0.1</version> <version>1.0.2</version>
<name>kafka-console-ui</name> <name>kafka-console-ui</name>
<description>Kafka console manage ui</description> <description>Kafka console manage ui</description>
<properties> <properties>

View File

@@ -29,6 +29,10 @@ public class TopicPartitionVO {
private long diff; private long diff;
private long beginTime;
private long endTime;
public static TopicPartitionVO from(TopicPartitionInfo partitionInfo) { public static TopicPartitionVO from(TopicPartitionInfo partitionInfo) {
TopicPartitionVO partitionVO = new TopicPartitionVO(); TopicPartitionVO partitionVO = new TopicPartitionVO();
partitionVO.setPartition(partitionInfo.partition()); partitionVO.setPartition(partitionInfo.partition());

View File

@@ -19,12 +19,14 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import kafka.console.MessageConsole;
import kafka.console.TopicConsole; import kafka.console.TopicConsole;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.admin.NewPartitions; import org.apache.kafka.clients.admin.NewPartitions;
import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.clients.admin.TopicDescription; import org.apache.kafka.clients.admin.TopicDescription;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.common.TopicPartition; import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.TopicPartitionInfo; import org.apache.kafka.common.TopicPartitionInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -44,6 +46,9 @@ public class TopicServiceImpl implements TopicService {
@Autowired @Autowired
private TopicConsole topicConsole; private TopicConsole topicConsole;
@Autowired
private MessageConsole messageConsole;
private Gson gson = GsonUtil.INSTANCE.get(); private Gson gson = GsonUtil.INSTANCE.get();
@Override public ResponseData getTopicNameList(boolean internal) { @Override public ResponseData getTopicNameList(boolean internal) {
@@ -106,6 +111,10 @@ public class TopicServiceImpl implements TopicService {
mapTuple2._2().forEach((k, v) -> { mapTuple2._2().forEach((k, v) -> {
endTable.put(k.partition(), (Long) v); endTable.put(k.partition(), (Long) v);
}); });
// computer the valid time range.
Map<TopicPartition, Object> beginOffsetTable = new HashMap<>();
Map<TopicPartition, Object> endOffsetTable = new HashMap<>();
Map<Integer, TopicPartition> partitionCache = new HashMap<>();
for (TopicPartitionVO partitionVO : voList) { for (TopicPartitionVO partitionVO : voList) {
long begin = beginTable.get(partitionVO.getPartition()); long begin = beginTable.get(partitionVO.getPartition());
@@ -113,7 +122,29 @@ public class TopicServiceImpl implements TopicService {
partitionVO.setBeginOffset(begin); partitionVO.setBeginOffset(begin);
partitionVO.setEndOffset(end); partitionVO.setEndOffset(end);
partitionVO.setDiff(end - begin); partitionVO.setDiff(end - begin);
if (begin != end) {
TopicPartition partition = new TopicPartition(topic, partitionVO.getPartition());
partitionCache.put(partitionVO.getPartition(), partition);
beginOffsetTable.put(partition, begin);
endOffsetTable.put(partition, end - 1); // end must < endOff
} else {
partitionVO.setBeginTime(-1L);
partitionVO.setEndTime(-1L);
}
} }
Map<TopicPartition, ConsumerRecord<byte[], byte[]>> beginRecordMap = messageConsole.searchBy(beginOffsetTable);
Map<TopicPartition, ConsumerRecord<byte[], byte[]>> endRecordMap = messageConsole.searchBy(endOffsetTable);
for (TopicPartitionVO partitionVO : voList) {
if (partitionVO.getBeginTime() != -1L) {
TopicPartition partition = partitionCache.get(partitionVO.getPartition());
partitionVO.setBeginTime(beginRecordMap.containsKey(partition) ? beginRecordMap.get(partition).timestamp() : -1L);
partitionVO.setEndTime(endRecordMap.containsKey(partition) ? endRecordMap.get(partition).timestamp() : -1L);
}
}
return ResponseData.create().data(voList).success(); return ResponseData.create().data(voList).success();
} }

View File

@@ -49,7 +49,15 @@
</a-button> </a-button>
</a-popconfirm> </a-popconfirm>
</div> </div>
<p slot="expandedRowRender" slot-scope="record" style="margin: 0">
有效消息的时间范围<span class="red-font">{{
formatTime(record.beginTime)
}}</span>
~
<span class="red-font">{{ formatTime(record.endTime) }}</span>
</p>
</a-table> </a-table>
<p>友情提示点击+号展开可以查看当前分区的有效消息的时间范围</p>
</a-spin> </a-spin>
</div> </div>
</a-modal> </a-modal>
@@ -59,6 +67,7 @@
import request from "@/utils/request"; import request from "@/utils/request";
import { KafkaOpApi, KafkaTopicApi } from "@/utils/api"; import { KafkaOpApi, KafkaTopicApi } from "@/utils/api";
import notification from "ant-design-vue/es/notification"; import notification from "ant-design-vue/es/notification";
import moment from "moment";
export default { export default {
name: "PartitionInfo", name: "PartitionInfo",
props: { props: {
@@ -128,6 +137,11 @@ export default {
} }
}); });
}, },
formatTime(timestamp) {
return timestamp != -1
? moment(timestamp).format("YYYY-MM-DD HH:mm:ss:SSS")
: timestamp;
},
}, },
}; };
@@ -169,6 +183,26 @@ const columns = [
dataIndex: "diff", dataIndex: "diff",
key: "diff", key: "diff",
}, },
// {
// title: "有效消息起始时间",
// dataIndex: "beginTime",
// key: "beginTime",
// slots: { title: "beginTime" },
// scopedSlots: { customRender: "internal" },
// customRender: (text) => {
// return text != -1 ? moment(text).format("YYYY-MM-DD HH:mm:ss:SSS") : text;
// },
// },
// {
// title: "有效消息结束时间",
// dataIndex: "endTime",
// key: "endTime",
// slots: { title: "endTime" },
// scopedSlots: { customRender: "internal" },
// customRender: (text) => {
// return text != -1 ? moment(text).format("YYYY-MM-DD HH:mm:ss:SSS") : text;
// },
// },
{ {
title: "操作", title: "操作",
key: "operation", key: "operation",
@@ -177,4 +211,8 @@ const columns = [
]; ];
</script> </script>
<style scoped></style> <style scoped>
.red-font {
color: red;
}
</style>