perf: 优化插件系统性能,消除重复实例化问题

- 添加plugins.Exists()函数,避免不必要的插件实例创建
- 合并PluginInfo数据结构,统一插件工厂和端口信息存储
- 修复Scanner中重复调用plugins.Get()的性能问题
- 优化BaseScanStrategy.pluginExists()实现效率

主要性能改进:
* 消除21×57=1197次不必要的本地插件实例化
* 提升插件存在性检查效率,从O(n)遍历优化为O(1)查找
* 改善数据内聚性,插件元数据集中管理
* 保持所有现有插件控制逻辑和功能完整性

测试验证:
* 无-local参数时不再创建本地插件实例
* 端口匹配、Web检测、互斥验证等功能正常
* 插件注册和执行逻辑保持向后兼容
This commit is contained in:
ZacharyZcR 2025-08-26 19:53:57 +08:00
parent 43ddb3630d
commit d981f0100f
3 changed files with 31 additions and 21 deletions

View File

@ -122,14 +122,8 @@ func (b *BaseScanStrategy) IsPluginApplicableByName(pluginName string, targetHos
// pluginExists 检查插件是否存在,不创建实例
func (b *BaseScanStrategy) pluginExists(pluginName string) bool {
// 使用All()获取所有注册插件名称避免调用Get()创建实例
allPlugins := plugins.All()
for _, name := range allPlugins {
if name == pluginName {
return true
}
}
return false
// 使用统一插件系统的Exists方法避免创建实例和遍历
return plugins.Exists(pluginName)
}
// getPluginPorts 获取插件端口列表

View File

@ -122,7 +122,8 @@ func ExecuteScanTasks(targets []common.HostInfo, strategy ScanStrategy, ch *chan
}
for _, pluginName := range pluginsToRun {
if plugins.Get(pluginName) == nil {
// 使用Exists检查避免不必要的插件实例创建
if !plugins.Exists(pluginName) {
continue
}
@ -144,7 +145,8 @@ func countApplicableTasks(targets []common.HostInfo, pluginsToRun []string, isCu
}
for _, pluginName := range pluginsToRun {
if plugins.Get(pluginName) != nil &&
// 使用Exists检查避免不必要的插件实例创建
if plugins.Exists(pluginName) &&
strategy.IsPluginApplicableByName(pluginName, target.Host, targetPort, isCustomMode) {
count++
}

View File

@ -55,26 +55,31 @@ type Credential struct {
KeyData []byte
}
// PluginInfo 插件信息结构 - 合并工厂和端口信息
type PluginInfo struct {
factory func() Plugin
ports []int
}
// 全局插件注册表 - 一个数据结构解决所有问题
var (
plugins = make(map[string]func() Plugin)
pluginPorts = make(map[string][]int) // 存储插件端口信息
plugins = make(map[string]*PluginInfo)
mutex sync.RWMutex
)
// Register 注册插件 - 一个函数统治所有注册
func Register(name string, factory func() Plugin) {
mutex.Lock()
defer mutex.Unlock()
plugins[name] = factory
RegisterWithPorts(name, factory, []int{})
}
// RegisterWithPorts 注册带端口信息的插件
func RegisterWithPorts(name string, factory func() Plugin, ports []int) {
mutex.Lock()
defer mutex.Unlock()
plugins[name] = factory
pluginPorts[name] = ports
plugins[name] = &PluginInfo{
factory: factory,
ports: ports,
}
}
// Get 获取插件实例
@ -82,8 +87,8 @@ func Get(name string) Plugin {
mutex.RLock()
defer mutex.RUnlock()
if factory, exists := plugins[name]; exists {
return factory()
if info, exists := plugins[name]; exists {
return info.factory()
}
return nil
}
@ -100,13 +105,22 @@ func All() []string {
return names
}
// Exists 检查插件是否存在,不创建实例 - 解决性能问题
func Exists(name string) bool {
mutex.RLock()
defer mutex.RUnlock()
_, exists := plugins[name]
return exists
}
// GetPluginPorts 获取插件端口列表
func GetPluginPorts(name string) []int {
mutex.RLock()
defer mutex.RUnlock()
if ports, exists := pluginPorts[name]; exists {
return ports
if info, exists := plugins[name]; exists {
return info.ports
}
return []int{} // 返回空列表表示适用于所有端口
}