1. ✅ 监控指标收集 2. ✅ 中间件机制 3. ✅ 配置热更新 4. ✅ 优雅关闭 5. ✅ 插件系统 6. ✅ API文档 7. ✅ 认证授权系统 8. ✅ 请求/响应压缩优化
163 lines
3.4 KiB
Go
163 lines
3.4 KiB
Go
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"plugin"
|
|
"sync"
|
|
)
|
|
|
|
// Plugin 插件接口
|
|
type Plugin interface {
|
|
// Name 插件名称
|
|
Name() string
|
|
// Version 插件版本
|
|
Version() string
|
|
// Init 初始化插件
|
|
Init(ctx context.Context) error
|
|
// Start 启动插件
|
|
Start(ctx context.Context) error
|
|
// Stop 停止插件
|
|
Stop(ctx context.Context) error
|
|
}
|
|
|
|
// PluginManager 插件管理器
|
|
type PluginManager struct {
|
|
pluginsDir string
|
|
plugins map[string]Plugin
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// NewPluginManager 创建插件管理器
|
|
func NewPluginManager(pluginsDir string) *PluginManager {
|
|
return &PluginManager{
|
|
pluginsDir: pluginsDir,
|
|
plugins: make(map[string]Plugin),
|
|
}
|
|
}
|
|
|
|
// LoadPlugins 加载插件
|
|
func (pm *PluginManager) LoadPlugins() error {
|
|
// 确保插件目录存在
|
|
if err := os.MkdirAll(pm.pluginsDir, 0755); err != nil {
|
|
return fmt.Errorf("创建插件目录失败: %v", err)
|
|
}
|
|
|
|
// 遍历插件目录
|
|
err := filepath.Walk(pm.pluginsDir, func(path string, info fs.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 跳过目录和非.so文件
|
|
if info.IsDir() || filepath.Ext(path) != ".so" {
|
|
return nil
|
|
}
|
|
|
|
// 加载插件
|
|
if err := pm.loadPlugin(path); err != nil {
|
|
fmt.Printf("加载插件 %s 失败: %v\n", path, err)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
// loadPlugin 加载单个插件
|
|
func (pm *PluginManager) loadPlugin(path string) error {
|
|
// 打开插件文件
|
|
p, err := plugin.Open(path)
|
|
if err != nil {
|
|
return fmt.Errorf("打开插件失败: %v", err)
|
|
}
|
|
|
|
// 查找Plugin变量
|
|
symPlugin, err := p.Lookup("Plugin")
|
|
if err != nil {
|
|
return fmt.Errorf("查找Plugin变量失败: %v", err)
|
|
}
|
|
|
|
// 类型断言
|
|
plugin, ok := symPlugin.(Plugin)
|
|
if !ok {
|
|
return errors.New("插件类型错误")
|
|
}
|
|
|
|
// 检查插件名称是否已存在
|
|
pm.mu.Lock()
|
|
if _, exists := pm.plugins[plugin.Name()]; exists {
|
|
pm.mu.Unlock()
|
|
return fmt.Errorf("插件 %s 已存在", plugin.Name())
|
|
}
|
|
pm.plugins[plugin.Name()] = plugin
|
|
pm.mu.Unlock()
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetPlugin 获取插件
|
|
func (pm *PluginManager) GetPlugin(name string) (Plugin, bool) {
|
|
pm.mu.RLock()
|
|
defer pm.mu.RUnlock()
|
|
|
|
plugin, exists := pm.plugins[name]
|
|
return plugin, exists
|
|
}
|
|
|
|
// GetAllPlugins 获取所有插件
|
|
func (pm *PluginManager) GetAllPlugins() []Plugin {
|
|
pm.mu.RLock()
|
|
defer pm.mu.RUnlock()
|
|
|
|
plugins := make([]Plugin, 0, len(pm.plugins))
|
|
for _, plugin := range pm.plugins {
|
|
plugins = append(plugins, plugin)
|
|
}
|
|
return plugins
|
|
}
|
|
|
|
// InitPlugins 初始化所有插件
|
|
func (pm *PluginManager) InitPlugins(ctx context.Context) error {
|
|
pm.mu.RLock()
|
|
defer pm.mu.RUnlock()
|
|
|
|
for name, plugin := range pm.plugins {
|
|
if err := plugin.Init(ctx); err != nil {
|
|
return fmt.Errorf("初始化插件 %s 失败: %v", name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// StartPlugins 启动所有插件
|
|
func (pm *PluginManager) StartPlugins(ctx context.Context) error {
|
|
pm.mu.RLock()
|
|
defer pm.mu.RUnlock()
|
|
|
|
for name, plugin := range pm.plugins {
|
|
if err := plugin.Start(ctx); err != nil {
|
|
return fmt.Errorf("启动插件 %s 失败: %v", name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// StopPlugins 停止所有插件
|
|
func (pm *PluginManager) StopPlugins(ctx context.Context) error {
|
|
pm.mu.RLock()
|
|
defer pm.mu.RUnlock()
|
|
|
|
for name, plugin := range pm.plugins {
|
|
if err := plugin.Stop(ctx); err != nil {
|
|
return fmt.Errorf("停止插件 %s 失败: %v", name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|