perf: optimize the performance of command monitor

This commit is contained in:
Lykin 2024-01-04 12:00:54 +08:00
parent ac6d68d17d
commit b823f18794
4 changed files with 32 additions and 11 deletions

View File

@ -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:

View File

@ -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) => {
data.list.push(content) if (content instanceof Array) {
data.list.push(...content)
} else {
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"

View File

@ -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",

View File

@ -362,6 +362,7 @@
"monitor": { "monitor": {
"title": "监控命令", "title": "监控命令",
"actions": "操作", "actions": "操作",
"warning": "命令监控可能会造成服务端堵塞,请谨慎在生产环境的服务器使用",
"start": "开启监控", "start": "开启监控",
"stop": "停止监控", "stop": "停止监控",
"search": "搜索", "search": "搜索",