mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 05:56:46 +08:00

- 重构插件注册架构采用现代工厂模式和自动发现机制 - 新增完整的插件元数据管理系统支持版本能力标签等信息 - 实现智能插件适配器提供向后兼容的桥接功能 - 建立MySQL Redis SSH三个标准插件作为新架构参考实现 - 优化插件扫描逻辑支持按端口按类型的智能查询和过滤 - 添加国际化支持和完善的文档体系 - 代码量减少67%维护成本大幅降低扩展性显著提升 新架构特点: - 零配置插件注册import即用 - 工厂模式延迟初始化和依赖注入 - 丰富元数据系统和能力声明 - 完全解耦的模块化设计 - 面向未来的可扩展架构 测试验证: MySQL和Redis插件功能完整包括弱密码检测未授权访问检测和自动利用攻击
140 lines
3.2 KiB
Go
140 lines
3.2 KiB
Go
package utils
|
||
|
||
import (
|
||
"log"
|
||
"runtime"
|
||
"time"
|
||
)
|
||
|
||
// MemoryMonitor 内存监控器
|
||
type MemoryMonitor struct {
|
||
maxHeapMB uint64 // 最大堆内存阈值(MB)
|
||
maxGoroutines int // 最大goroutine数量阈值
|
||
checkInterval time.Duration // 检查间隔
|
||
running bool // 是否运行中
|
||
stopChan chan bool
|
||
}
|
||
|
||
// NewMemoryMonitor 创建新的内存监控器
|
||
func NewMemoryMonitor(maxHeapMB uint64, maxGoroutines int, checkInterval time.Duration) *MemoryMonitor {
|
||
return &MemoryMonitor{
|
||
maxHeapMB: maxHeapMB,
|
||
maxGoroutines: maxGoroutines,
|
||
checkInterval: checkInterval,
|
||
stopChan: make(chan bool, 1),
|
||
}
|
||
}
|
||
|
||
// Start 启动内存监控
|
||
func (mm *MemoryMonitor) Start() {
|
||
if mm.running {
|
||
return
|
||
}
|
||
|
||
mm.running = true
|
||
go mm.monitor()
|
||
}
|
||
|
||
// Stop 停止内存监控
|
||
func (mm *MemoryMonitor) Stop() {
|
||
if !mm.running {
|
||
return
|
||
}
|
||
|
||
mm.running = false
|
||
select {
|
||
case mm.stopChan <- true:
|
||
default:
|
||
}
|
||
}
|
||
|
||
// monitor 监控循环
|
||
func (mm *MemoryMonitor) monitor() {
|
||
ticker := time.NewTicker(mm.checkInterval)
|
||
defer ticker.Stop()
|
||
|
||
for {
|
||
select {
|
||
case <-ticker.C:
|
||
mm.checkMemory()
|
||
case <-mm.stopChan:
|
||
return
|
||
}
|
||
}
|
||
}
|
||
|
||
// checkMemory 检查内存使用情况
|
||
func (mm *MemoryMonitor) checkMemory() {
|
||
var m runtime.MemStats
|
||
runtime.ReadMemStats(&m)
|
||
|
||
heapMB := m.HeapInuse / 1024 / 1024
|
||
goroutineCount := runtime.NumGoroutine()
|
||
|
||
// 检查堆内存使用
|
||
if heapMB > mm.maxHeapMB {
|
||
log.Printf("[WARN] 内存使用警告: 堆内存使用过高 %d MB (阈值: %d MB)", heapMB, mm.maxHeapMB)
|
||
|
||
// 尝试触发GC
|
||
runtime.GC()
|
||
|
||
// 再次检查
|
||
runtime.ReadMemStats(&m)
|
||
heapMBAfterGC := m.HeapInuse / 1024 / 1024
|
||
log.Printf("[INFO] GC后堆内存: %d MB", heapMBAfterGC)
|
||
}
|
||
|
||
// 检查goroutine数量
|
||
if goroutineCount > mm.maxGoroutines {
|
||
log.Printf("[WARN] Goroutine数量警告: 当前数量 %d (阈值: %d)", goroutineCount, mm.maxGoroutines)
|
||
}
|
||
}
|
||
|
||
// GetMemoryStats 获取当前内存统计信息
|
||
func (mm *MemoryMonitor) GetMemoryStats() map[string]interface{} {
|
||
var m runtime.MemStats
|
||
runtime.ReadMemStats(&m)
|
||
|
||
return map[string]interface{}{
|
||
"heap_inuse_mb": m.HeapInuse / 1024 / 1024,
|
||
"heap_alloc_mb": m.HeapAlloc / 1024 / 1024,
|
||
"sys_mb": m.Sys / 1024 / 1024,
|
||
"num_gc": m.NumGC,
|
||
"num_goroutines": runtime.NumGoroutine(),
|
||
"last_gc_time": time.Unix(0, int64(m.LastGC)),
|
||
}
|
||
}
|
||
|
||
// ForceGC 强制执行垃圾回收
|
||
func (mm *MemoryMonitor) ForceGC() {
|
||
before := mm.getHeapSize()
|
||
runtime.GC()
|
||
after := mm.getHeapSize()
|
||
|
||
// 使用log包直接输出,避免undefined common错误
|
||
log.Printf("[INFO] 强制GC: 释放内存 %d MB", (before-after)/1024/1024)
|
||
}
|
||
|
||
// getHeapSize 获取当前堆大小
|
||
func (mm *MemoryMonitor) getHeapSize() uint64 {
|
||
var m runtime.MemStats
|
||
runtime.ReadMemStats(&m)
|
||
return m.HeapInuse
|
||
}
|
||
|
||
// 默认内存监控器实例
|
||
var DefaultMemMonitor = NewMemoryMonitor(
|
||
512, // 最大堆内存512MB
|
||
1000, // 最大1000个goroutines
|
||
30*time.Second, // 30秒检查一次
|
||
)
|
||
|
||
// StartDefaultMonitor 启动默认内存监控器
|
||
func StartDefaultMonitor() {
|
||
DefaultMemMonitor.Start()
|
||
}
|
||
|
||
// StopDefaultMonitor 停止默认内存监控器
|
||
func StopDefaultMonitor() {
|
||
DefaultMemMonitor.Stop()
|
||
} |