按时间查询消息及时释放内存

This commit is contained in:
许晓东
2021-12-17 20:06:23 +08:00
parent b9548d1640
commit bd814d550d
5 changed files with 191 additions and 14 deletions

View File

@@ -8,7 +8,7 @@ import java.time.Duration
import java.util
import java.util.Properties
import scala.collection.immutable
import scala.jdk.CollectionConverters.{CollectionHasAsScala, MapHasAsScala}
import scala.jdk.CollectionConverters.{CollectionHasAsScala, MapHasAsScala, SeqHasAsJava}
/**
* kafka-console-ui.
@@ -60,20 +60,48 @@ class MessageConsole(config: KafkaConfig) extends KafkaConsole(config: KafkaConf
} else {
for ((tp, endOff) <- endOffTable) {
if (!terminate) {
val recordList = records.records(tp)
var recordList = records.records(tp)
if (!recordList.isEmpty) {
val first = recordList.get(0)
if (first.offset() >= endOff) {
arrive.remove(tp)
} else {
res.addAll(recordList)
//
// (String topic,
// int partition,
// long offset,
// long timestamp,
// TimestampType timestampType,
// Long checksum,
// int serializedKeySize,
// int serializedValueSize,
// K key,
// V value,
// Headers headers,
// Optional<Integer> leaderEpoch)
val nullVList = recordList.asScala.map(record => new ConsumerRecord[Array[Byte], Array[Byte]](record.topic(),
record.partition(),
record.offset(),
record.timestamp(),
record.timestampType(),
record.checksum(),
record.serializedKeySize(),
record.serializedValueSize(),
record.key(),
null,
record.headers(),
record.leaderEpoch())).toSeq.asJava
res.addAll(nullVList)
if (recordList.get(recordList.size() - 1).offset() >= endOff) {
arrive.remove(tp)
}
if (recordList != null) {
recordList = null
}
}
}
if (arrive.isEmpty) {
terminate = true;
terminate = true
}
}
}

View File

@@ -5,10 +5,12 @@
<a-tab-pane key="1" tab="根据时间查询消息">
<SearchByTime :topic-list="topicList"></SearchByTime>
</a-tab-pane>
<a-tab-pane key="2" tab="根据偏移查询消息" force-render>
<a-tab-pane key="2" tab="根据偏移查询消息">
<SearchByOffset :topic-list="topicList"></SearchByOffset>
</a-tab-pane>
<!-- <a-tab-pane key="3" tab="消息发送"> 消息发送1 </a-tab-pane>-->
<a-tab-pane key="3" tab="在线发送">
<SendMessage :topic-list="topicList"></SendMessage>
</a-tab-pane>
</a-tabs>
</a-spin>
</div>
@@ -20,9 +22,10 @@ import SearchByOffset from "@/views/message/SearchByOffset";
import request from "@/utils/request";
import { KafkaTopicApi } from "@/utils/api";
import notification from "ant-design-vue/lib/notification";
import SendMessage from "@/views/message/SendMessage";
export default {
name: "Message",
components: { SearchByTime, SearchByOffset },
components: { SearchByTime, SearchByOffset, SendMessage },
data() {
return {
loading: false,

View File

@@ -1,7 +1,7 @@
<template>
<div class="tab-content">
<a-spin :spinning="loading">
<div id="components-form-advanced-search">
<div id="search-offset-form-advanced-search">
<a-form
class="ant-advanced-search-form"
:form="form"
@@ -87,7 +87,7 @@ export default {
data() {
return {
loading: false,
form: this.$form.createForm(this, { name: "message_search_time" }),
form: this.$form.createForm(this, { name: "message_search_offset" }),
partitions: [],
selectPartition: undefined,
rangeConfig: {
@@ -97,7 +97,8 @@ export default {
};
},
methods: {
handleSearch() {
handleSearch(e) {
e.preventDefault();
this.form.validateFields((err, values) => {
if (!err) {
const data = Object.assign({}, values, {
@@ -176,7 +177,7 @@ const defaultData = [];
margin-bottom: 1%;
}
#components-form-advanced-search .search-result-list {
#search-offset-form-advanced-search .search-result-list {
margin-top: 16px;
border: 1px dashed #e9e9e9;
border-radius: 6px;

View File

@@ -1,7 +1,7 @@
<template>
<div class="tab-content">
<a-spin :spinning="loading">
<div id="components-form-advanced-search">
<div id="search-time-form-advanced-search">
<a-form
class="ant-advanced-search-form"
:form="form"
@@ -100,7 +100,8 @@ export default {
};
},
methods: {
handleSearch() {
handleSearch(e) {
e.preventDefault();
this.form.validateFields((err, values) => {
if (!err) {
const data = Object.assign({}, values, {
@@ -181,7 +182,7 @@ const defaultData = { realNum: 0, maxNum: 0 };
margin-bottom: 1%;
}
#components-form-advanced-search .search-result-list {
#search-time-form-advanced-search .search-result-list {
margin-top: 16px;
border: 1px dashed #e9e9e9;
border-radius: 6px;

View File

@@ -0,0 +1,144 @@
<template>
<div class="content">
<a-spin :spinning="loading">
<a-form :form="form">
<a-form-item label="Topic">
<a-select
class="topic-select"
@change="handleTopicChange"
show-search
option-filter-prop="children"
v-decorator="[
'topic',
{
rules: [{ required: true, message: '请选择一个topic!' }],
},
]"
placeholder="请选择一个topic"
>
<a-select-option v-for="v in topicList" :key="v" :value="v">
{{ v }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="分区">
<a-select
class="type-select"
show-search
option-filter-prop="children"
v-model="selectPartition"
placeholder="请选择一个分区"
>
<a-select-option v-for="v in partitions" :key="v" :value="v">
<span v-if="v == -1">默认</span> <span v-else>{{ v }}</span>
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="消息Key">
<a-input v-decorator="['key', { initialValue: 'key' }]" />
</a-form-item>
<a-form-item label="消息体" has-feedback>
<a-input
v-decorator="[
'body',
{
rules: [
{
required: true,
message: '输入消息体!',
},
],
},
]"
placeholder="输入消息体!"
/>
</a-form-item>
<a-form-item label="发送的消息数">
<a-input-number
v-decorator="[
'nums',
{
initialValue: 1,
rules: [
{
required: true,
message: '输入消息数!',
},
],
},
]"
:min="1"
:max="32"
/>
</a-form-item>
</a-form>
</a-spin>
</div>
</template>
<script>
import request from "@/utils/request";
import { KafkaTopicApi } from "@/utils/api";
import notification from "ant-design-vue/lib/notification";
export default {
name: "SendMessage",
components: {},
props: {
topicList: {
type: Array,
},
},
data() {
return {
form: this.$form.createForm(this, { name: "message_send" }),
loading: false,
partitions: [],
selectPartition: undefined,
};
},
methods: {
getTopicNameList() {
request({
url: KafkaTopicApi.getTopicNameList.url,
method: KafkaTopicApi.getTopicNameList.method,
}).then((res) => {
if (res.code == 0) {
this.topicList = res.data;
} else {
notification.error({
message: "error",
description: res.msg,
});
}
});
},
getPartitionInfo(topic) {
this.loading = true;
request({
url: KafkaTopicApi.getPartitionInfo.url + "?topic=" + topic,
method: KafkaTopicApi.getPartitionInfo.method,
}).then((res) => {
this.loading = false;
if (res.code != 0) {
notification.error({
message: "error",
description: res.msg,
});
} else {
this.partitions = res.data.map((v) => v.partition);
this.partitions.splice(0, 0, -1);
}
});
},
handleTopicChange(topic) {
this.selectPartition = -1;
this.getPartitionInfo(topic);
},
},
created() {
this.getTopicNameList();
},
};
</script>
<style scoped></style>