feat(server): 集成 Lua 中间件到服务器生命周期

- 在 Server 结构添加 luaEngine 字段
- 实现 buildLuaMiddlewares 按阶段创建中间件
- 在 Start() 初始化 Lua 引擎,Stop/GracefulStop 关闭

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-04-11 14:31:48 +08:00
parent 1e545717fb
commit 153982121e

View File

@ -34,6 +34,7 @@ import (
"rua.plus/lolly/internal/handler" "rua.plus/lolly/internal/handler"
"rua.plus/lolly/internal/loadbalance" "rua.plus/lolly/internal/loadbalance"
"rua.plus/lolly/internal/logging" "rua.plus/lolly/internal/logging"
"rua.plus/lolly/internal/lua"
"rua.plus/lolly/internal/middleware" "rua.plus/lolly/internal/middleware"
"rua.plus/lolly/internal/middleware/accesslog" "rua.plus/lolly/internal/middleware/accesslog"
"rua.plus/lolly/internal/middleware/bodylimit" "rua.plus/lolly/internal/middleware/bodylimit"
@ -111,6 +112,9 @@ type Server struct {
// resolver DNS 解析器(可选) // resolver DNS 解析器(可选)
resolver resolver.Resolver resolver resolver.Resolver
// luaEngine Lua 引擎(可选)
luaEngine *lua.LuaEngine
} }
// New 创建 HTTP 服务器实例。 // New 创建 HTTP 服务器实例。
@ -316,9 +320,108 @@ func (s *Server) buildMiddlewareChain(serverCfg *config.ServerConfig) (*middlewa
middlewares = append(middlewares, ei) middlewares = append(middlewares, ei)
} }
// Lua 中间件(可选)
if s.luaEngine != nil && serverCfg.Lua != nil && serverCfg.Lua.Enabled {
luaMiddlewares, err := s.buildLuaMiddlewares(serverCfg.Lua)
if err != nil {
return nil, fmt.Errorf("创建 Lua 中间件失败: %w", err)
}
middlewares = append(middlewares, luaMiddlewares...)
}
return middleware.NewChain(middlewares...), nil return middleware.NewChain(middlewares...), nil
} }
// buildLuaMiddlewares 根据 Lua 配置创建中间件。
//
// 根据 Scripts 配置创建 LuaMiddleware 或 MultiPhaseLuaMiddleware。
// 支持单脚本和多阶段脚本配置。
//
// 参数:
// - luaCfg: Lua 配置对象
//
// 返回值:
// - []middleware.Middleware: 创建的中间件列表
// - error: 创建过程中遇到的错误
func (s *Server) buildLuaMiddlewares(luaCfg *config.LuaMiddlewareConfig) ([]middleware.Middleware, error) {
if s.luaEngine == nil {
return nil, nil
}
// 按阶段分组脚本
phaseScripts := make(map[string][]config.LuaScriptConfig)
for _, script := range luaCfg.Scripts {
// 默认启用
enabled := script.Enabled
if !enabled && script.Timeout == 0 && script.Path != "" {
enabled = true // 零值时默认启用
}
if enabled {
phaseScripts[script.Phase] = append(phaseScripts[script.Phase], script)
}
}
var middlewares []middleware.Middleware
// 为每个阶段创建中间件
for phase, scripts := range phaseScripts {
if len(scripts) == 0 {
continue
}
// 单脚本:直接创建 LuaMiddleware
if len(scripts) == 1 {
script := scripts[0]
luaPhase, err := lua.ParsePhase(phase)
if err != nil {
return nil, fmt.Errorf("无效的阶段 '%s': %w", phase, err)
}
timeout := script.Timeout
if timeout == 0 {
timeout = 30 * time.Second
}
cfg := lua.LuaMiddlewareConfig{
ScriptPath: script.Path,
Phase: luaPhase,
Timeout: timeout,
Name: fmt.Sprintf("lua-%s", phase),
}
mw, err := lua.NewLuaMiddleware(s.luaEngine, cfg)
if err != nil {
return nil, fmt.Errorf("创建 Lua 中间件失败 (phase=%s): %w", phase, err)
}
middlewares = append(middlewares, mw)
} else {
// 多脚本:创建 MultiPhaseLuaMiddleware
multi := lua.NewMultiPhaseLuaMiddleware(s.luaEngine, fmt.Sprintf("lua-multi-%s", phase))
for _, script := range scripts {
luaPhase, err := lua.ParsePhase(phase)
if err != nil {
return nil, fmt.Errorf("无效的阶段 '%s': %w", phase, err)
}
timeout := script.Timeout
if timeout == 0 {
timeout = 30 * time.Second
}
err = multi.AddPhase(luaPhase, script.Path, timeout)
if err != nil {
return nil, fmt.Errorf("添加 Lua 阶段失败 (phase=%s): %w", phase, err)
}
}
middlewares = append(middlewares, multi)
}
}
return middlewares, nil
}
// Start 启动 HTTP 服务器。 // Start 启动 HTTP 服务器。
// //
// 初始化日志系统、性能优化组件Goroutine池、文件缓存 // 初始化日志系统、性能优化组件Goroutine池、文件缓存
@ -371,6 +474,41 @@ func (s *Server) Start() error {
} }
} }
// 初始化 Lua 引擎(如果配置)
if s.config.Server.Lua != nil && s.config.Server.Lua.Enabled {
engineCfg := &lua.Config{
MaxConcurrentCoroutines: s.config.Server.Lua.GlobalSettings.MaxConcurrentCoroutines,
CoroutineTimeout: s.config.Server.Lua.GlobalSettings.CoroutineTimeout,
CodeCacheSize: s.config.Server.Lua.GlobalSettings.CodeCacheSize,
CodeCacheTTL: time.Hour, // 默认值
EnableFileWatch: s.config.Server.Lua.GlobalSettings.EnableFileWatch,
MaxExecutionTime: s.config.Server.Lua.GlobalSettings.MaxExecutionTime,
EnableOSLib: false, // 安全默认值
EnableIOLib: false,
EnableLoadLib: false,
}
// 设置默认值
if engineCfg.MaxConcurrentCoroutines == 0 {
engineCfg.MaxConcurrentCoroutines = 1000
}
if engineCfg.CoroutineTimeout == 0 {
engineCfg.CoroutineTimeout = 30 * time.Second
}
if engineCfg.CodeCacheSize == 0 {
engineCfg.CodeCacheSize = 1000
}
if engineCfg.MaxExecutionTime == 0 {
engineCfg.MaxExecutionTime = 30 * time.Second
}
var err error
s.luaEngine, err = lua.NewEngine(engineCfg)
if err != nil {
return fmt.Errorf("初始化 Lua 引擎失败: %w", err)
}
logging.Info().Msg("Lua 引擎已启动")
}
if s.config.HasServers() { if s.config.HasServers() {
return s.startVHostMode() return s.startVHostMode()
} }
@ -674,6 +812,12 @@ func (s *Server) Stop() error {
s.tlsManager.Close() s.tlsManager.Close()
} }
// 关闭 Lua 引擎
if s.luaEngine != nil {
s.luaEngine.Close()
logging.Info().Msg("Lua 引擎已关闭")
}
if s.fastServer != nil { if s.fastServer != nil {
return s.fastServer.Shutdown() return s.fastServer.Shutdown()
} }
@ -717,6 +861,12 @@ func (s *Server) GracefulStop(timeout time.Duration) error {
s.tlsManager.Close() s.tlsManager.Close()
} }
// 关闭 Lua 引擎
if s.luaEngine != nil {
s.luaEngine.Close()
logging.Info().Msg("Lua 引擎已关闭")
}
if s.fastServer != nil { if s.fastServer != nil {
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel() defer cancel()