perf: optimize the performance of command monitor
This commit is contained in:
parent
ac6d68d17d
commit
b823f18794
|
@ -17,6 +17,7 @@ import (
|
||||||
type monitorItem struct {
|
type monitorItem struct {
|
||||||
client *redis.Client
|
client *redis.Client
|
||||||
cmd *redis.MonitorCmd
|
cmd *redis.MonitorCmd
|
||||||
|
mutex sync.Mutex
|
||||||
ch chan string
|
ch chan string
|
||||||
closeCh chan struct{}
|
closeCh chan struct{}
|
||||||
eventName string
|
eventName string
|
||||||
|
@ -88,7 +89,7 @@ func (c *monitorService) StartMonitor(server string) (resp types.JSResp) {
|
||||||
item.cmd = item.client.Monitor(c.ctx, item.ch)
|
item.cmd = item.client.Monitor(c.ctx, item.ch)
|
||||||
item.cmd.Start()
|
item.cmd.Start()
|
||||||
|
|
||||||
go c.processMonitor(item.ch, item.closeCh, item.eventName)
|
go c.processMonitor(&item.mutex, item.ch, item.closeCh, item.eventName)
|
||||||
resp.Success = true
|
resp.Success = true
|
||||||
resp.Data = struct {
|
resp.Data = struct {
|
||||||
EventName string `json:"eventName"`
|
EventName string `json:"eventName"`
|
||||||
|
@ -98,12 +99,23 @@ func (c *monitorService) StartMonitor(server string) (resp types.JSResp) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *monitorService) processMonitor(ch <-chan string, closeCh <-chan struct{}, eventName string) {
|
func (c *monitorService) processMonitor(mutex *sync.Mutex, ch <-chan string, closeCh <-chan struct{}, eventName string) {
|
||||||
|
lastEmitTime := time.Now().Add(-1 * time.Minute)
|
||||||
|
cache := make([]string, 0, 1000)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case data := <-ch:
|
case data := <-ch:
|
||||||
if data != "OK" {
|
if data != "OK" {
|
||||||
runtime.EventsEmit(c.ctx, eventName, data)
|
go func() {
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
cache = append(cache, data)
|
||||||
|
if time.Now().Sub(lastEmitTime) > 1*time.Second || len(cache) > 300 {
|
||||||
|
runtime.EventsEmit(c.ctx, eventName, cache)
|
||||||
|
cache = cache[:0:cap(cache)]
|
||||||
|
lastEmitTime = time.Now()
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-closeCh:
|
case <-closeCh:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
|
import { computed, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
import { filter, get, includes, isEmpty, join } from 'lodash'
|
import { debounce, filter, get, includes, isEmpty, join } from 'lodash'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useThemeVars } from 'naive-ui'
|
import { useThemeVars } from 'naive-ui'
|
||||||
import useBrowserStore from 'stores/browser.js'
|
import useBrowserStore from 'stores/browser.js'
|
||||||
|
@ -53,6 +53,13 @@ const displayList = computed(() => {
|
||||||
return data.list
|
return data.list
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const _scrollToBottom = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
listRef.value?.scrollTo({ position: 'bottom' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const scrollToBottom = debounce(_scrollToBottom, 1000, { leading: true, trailing: true })
|
||||||
|
|
||||||
const onStartMonitor = async () => {
|
const onStartMonitor = async () => {
|
||||||
if (isMonitoring.value) {
|
if (isMonitoring.value) {
|
||||||
return
|
return
|
||||||
|
@ -65,11 +72,13 @@ const onStartMonitor = async () => {
|
||||||
}
|
}
|
||||||
data.monitorEvent = get(ret, 'eventName')
|
data.monitorEvent = get(ret, 'eventName')
|
||||||
EventsOn(data.monitorEvent, (content) => {
|
EventsOn(data.monitorEvent, (content) => {
|
||||||
|
if (content instanceof Array) {
|
||||||
|
data.list.push(...content)
|
||||||
|
} else {
|
||||||
data.list.push(content)
|
data.list.push(content)
|
||||||
|
}
|
||||||
if (data.autoShowLast) {
|
if (data.autoShowLast) {
|
||||||
nextTick(() => {
|
scrollToBottom()
|
||||||
listRef.value.scrollTo({ position: 'bottom' })
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -108,7 +117,7 @@ const onCleanLog = () => {
|
||||||
<template>
|
<template>
|
||||||
<div class="content-log content-container fill-height flex-box-v">
|
<div class="content-log content-container fill-height flex-box-v">
|
||||||
<n-form class="flex-item" label-align="left" label-placement="left" label-width="auto" size="small">
|
<n-form class="flex-item" label-align="left" label-placement="left" label-width="auto" size="small">
|
||||||
<n-form-item :label="$t('monitor.actions')">
|
<n-form-item :feedback="$t('monitor.warning')" :label="$t('monitor.actions')">
|
||||||
<n-space>
|
<n-space>
|
||||||
<n-button
|
<n-button
|
||||||
v-if="!isMonitoring"
|
v-if="!isMonitoring"
|
||||||
|
|
|
@ -305,8 +305,6 @@
|
||||||
},
|
},
|
||||||
"upgrade": {
|
"upgrade": {
|
||||||
"title": "New Version Available",
|
"title": "New Version Available",
|
||||||
"import_expire_title": "Expiration",
|
|
||||||
"import_expire": "Include Expiration Time",
|
|
||||||
"new_version_tip": "A new version({ver}) is available. Download now?",
|
"new_version_tip": "A new version({ver}) is available. Download now?",
|
||||||
"no_update": "You're update to date",
|
"no_update": "You're update to date",
|
||||||
"download_now": "Download",
|
"download_now": "Download",
|
||||||
|
@ -364,6 +362,7 @@
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"title": "Monitor Commands",
|
"title": "Monitor Commands",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
|
"warning": "Monitor command may lead to server congestion. Please use it cautiously on production servers.",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"stop": "Stop",
|
"stop": "Stop",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
|
|
|
@ -362,6 +362,7 @@
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"title": "监控命令",
|
"title": "监控命令",
|
||||||
"actions": "操作",
|
"actions": "操作",
|
||||||
|
"warning": "命令监控可能会造成服务端堵塞,请谨慎在生产环境的服务器使用",
|
||||||
"start": "开启监控",
|
"start": "开启监控",
|
||||||
"stop": "停止监控",
|
"stop": "停止监控",
|
||||||
"search": "搜索",
|
"search": "搜索",
|
||||||
|
|
Loading…
Reference in New Issue