Files
pansou/main.go

245 lines
6.6 KiB
Go
Raw Normal View History

2025-07-12 19:53:44 +08:00
package main
import (
2025-07-15 00:03:02 +08:00
"context"
2025-07-12 19:53:44 +08:00
"fmt"
"log"
2025-07-23 12:01:09 +08:00
"net"
2025-07-15 00:03:02 +08:00
"net/http"
"os"
"os/signal"
2025-07-23 12:01:09 +08:00
"runtime"
2025-07-15 00:03:02 +08:00
"syscall"
"time"
2025-07-12 19:53:44 +08:00
2025-07-23 12:01:09 +08:00
"golang.org/x/net/netutil"
2025-07-12 19:53:44 +08:00
"pansou/api"
"pansou/config"
"pansou/plugin"
// 以下是插件的空导入用于触发各插件的init函数实现自动注册
// 添加新插件时,只需在此处添加对应的导入语句即可
2025-07-29 21:43:56 +08:00
_ "pansou/plugin/hdr4k"
2025-07-15 00:03:02 +08:00
_ "pansou/plugin/hunhepan"
2025-07-12 19:53:44 +08:00
_ "pansou/plugin/jikepan"
2025-07-15 00:03:02 +08:00
_ "pansou/plugin/pan666"
2025-07-12 19:53:44 +08:00
_ "pansou/plugin/pansearch"
2025-07-15 00:03:02 +08:00
_ "pansou/plugin/panta"
2025-07-12 19:53:44 +08:00
_ "pansou/plugin/qupansou"
2025-07-22 21:15:43 +08:00
_ "pansou/plugin/susu"
2025-07-25 11:22:02 +08:00
_ "pansou/plugin/panyq"
2025-07-25 12:17:12 +08:00
_ "pansou/plugin/xuexizhinan"
2025-07-12 19:53:44 +08:00
"pansou/service"
"pansou/util"
)
func main() {
// 初始化应用
initApp()
// 启动服务器
startServer()
}
// initApp 初始化应用程序
func initApp() {
// 初始化配置
config.Init()
// 初始化HTTP客户端
util.InitHTTPClient()
2025-07-15 00:03:02 +08:00
// 确保异步插件系统初始化
plugin.InitAsyncPluginSystem()
2025-07-12 19:53:44 +08:00
}
// startServer 启动Web服务器
func startServer() {
// 初始化插件管理器
pluginManager := plugin.NewPluginManager()
// 注册所有全局插件通过init函数自动注册到全局注册表
pluginManager.RegisterAllGlobalPlugins()
2025-07-23 12:01:09 +08:00
// 更新默认并发数(使用实际插件数)
config.UpdateDefaultConcurrency(len(pluginManager.GetPlugins()))
2025-07-12 19:53:44 +08:00
// 初始化搜索服务
searchService := service.NewSearchService(pluginManager)
// 设置路由
router := api.SetupRouter(searchService)
// 获取端口配置
port := config.AppConfig.Port
// 输出服务信息
printServiceInfo(port, pluginManager)
2025-07-15 00:03:02 +08:00
// 创建HTTP服务器
srv := &http.Server{
2025-07-23 12:01:09 +08:00
Addr: ":" + port,
Handler: router,
ReadTimeout: config.AppConfig.HTTPReadTimeout,
WriteTimeout: config.AppConfig.HTTPWriteTimeout,
IdleTimeout: config.AppConfig.HTTPIdleTimeout,
2025-07-15 00:03:02 +08:00
}
// 创建通道来接收操作系统信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// 在单独的goroutine中启动服务器
go func() {
2025-07-23 12:01:09 +08:00
// 如果设置了最大连接数,使用限制监听器
if config.AppConfig.HTTPMaxConns > 0 {
// 创建监听器
listener, err := net.Listen("tcp", srv.Addr)
if err != nil {
log.Fatalf("创建监听器失败: %v", err)
}
// 创建限制连接数的监听器
limitListener := netutil.LimitListener(listener, config.AppConfig.HTTPMaxConns)
// 使用限制监听器启动服务器
if err := srv.Serve(limitListener); err != nil && err != http.ErrServerClosed {
log.Fatalf("启动服务器失败: %v", err)
}
} else {
// 使用默认方式启动服务器(不限制连接数)
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("启动服务器失败: %v", err)
}
2025-07-15 00:03:02 +08:00
}
}()
// 等待中断信号
<-quit
fmt.Println("正在关闭服务器...")
// 设置关闭超时时间
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 异步插件本地缓存系统已移除
2025-07-15 00:03:02 +08:00
// 优雅关闭服务器
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("服务器关闭异常: %v", err)
2025-07-12 19:53:44 +08:00
}
2025-07-15 00:03:02 +08:00
fmt.Println("服务器已安全关闭")
2025-07-12 19:53:44 +08:00
}
// printServiceInfo 打印服务信息
func printServiceInfo(port string, pluginManager *plugin.PluginManager) {
// 启动服务器
fmt.Printf("服务器启动在 http://localhost:%s\n", port)
// 输出代理信息
if config.AppConfig.UseProxy {
fmt.Printf("使用SOCKS5代理: %s\n", config.AppConfig.ProxyURL)
} else {
fmt.Println("未使用代理")
}
2025-07-23 12:01:09 +08:00
// 输出并发信息
if os.Getenv("CONCURRENCY") != "" {
fmt.Printf("默认并发数: %d (由环境变量CONCURRENCY指定)\n", config.AppConfig.DefaultConcurrency)
} else {
channelCount := len(config.AppConfig.DefaultChannels)
pluginCount := 0
if pluginManager != nil {
pluginCount = len(pluginManager.GetPlugins())
}
fmt.Printf("默认并发数: %d (= 频道数%d + 插件数%d + 10)\n",
config.AppConfig.DefaultConcurrency, channelCount, pluginCount)
}
2025-07-12 19:53:44 +08:00
// 输出缓存信息
if config.AppConfig.CacheEnabled {
fmt.Printf("缓存已启用: 路径=%s, 最大大小=%dMB, TTL=%d分钟\n",
config.AppConfig.CachePath,
config.AppConfig.CacheMaxSizeMB,
config.AppConfig.CacheTTLMinutes)
} else {
fmt.Println("缓存已禁用")
}
// 输出压缩信息
if config.AppConfig.EnableCompression {
fmt.Printf("响应压缩已启用: 最小压缩大小=%d字节\n",
config.AppConfig.MinSizeToCompress)
} else {
fmt.Println("响应压缩已禁用")
}
// 输出GC配置信息
fmt.Printf("GC配置: 触发阈值=%d%%, 内存优化=%v\n",
config.AppConfig.GCPercent,
config.AppConfig.OptimizeMemory)
2025-07-23 12:01:09 +08:00
// 输出HTTP服务器配置信息
readTimeoutMsg := ""
if os.Getenv("HTTP_READ_TIMEOUT") != "" {
readTimeoutMsg = "(由环境变量指定)"
} else {
readTimeoutMsg = "(自动计算)"
}
writeTimeoutMsg := ""
if os.Getenv("HTTP_WRITE_TIMEOUT") != "" {
writeTimeoutMsg = "(由环境变量指定)"
} else {
writeTimeoutMsg = "(自动计算)"
}
maxConnsMsg := ""
if os.Getenv("HTTP_MAX_CONNS") != "" {
maxConnsMsg = "(由环境变量指定)"
} else {
cpuCount := runtime.NumCPU()
maxConnsMsg = fmt.Sprintf("(自动计算: CPU核心数%d × 200)", cpuCount)
}
fmt.Printf("HTTP服务器配置: 读取超时=%v %s, 写入超时=%v %s, 空闲超时=%v, 最大连接数=%d %s\n",
config.AppConfig.HTTPReadTimeout, readTimeoutMsg,
config.AppConfig.HTTPWriteTimeout, writeTimeoutMsg,
config.AppConfig.HTTPIdleTimeout,
config.AppConfig.HTTPMaxConns, maxConnsMsg)
2025-07-15 00:03:02 +08:00
// 输出异步插件配置信息
if config.AppConfig.AsyncPluginEnabled {
2025-07-23 12:01:09 +08:00
// 检查工作者数量是否由环境变量指定
workersMsg := ""
if os.Getenv("ASYNC_MAX_BACKGROUND_WORKERS") != "" {
workersMsg = "(由环境变量指定)"
} else {
cpuCount := runtime.NumCPU()
workersMsg = fmt.Sprintf("(自动计算: CPU核心数%d × 5)", cpuCount)
}
// 检查任务数量是否由环境变量指定
tasksMsg := ""
if os.Getenv("ASYNC_MAX_BACKGROUND_TASKS") != "" {
tasksMsg = "(由环境变量指定)"
} else {
tasksMsg = "(自动计算: 工作者数量 × 5)"
}
fmt.Printf("异步插件已启用: 响应超时=%d秒, 最大工作者=%d %s, 最大任务=%d %s, 缓存TTL=%d小时\n",
2025-07-15 00:03:02 +08:00
config.AppConfig.AsyncResponseTimeout,
2025-07-23 12:01:09 +08:00
config.AppConfig.AsyncMaxBackgroundWorkers, workersMsg,
config.AppConfig.AsyncMaxBackgroundTasks, tasksMsg,
2025-07-15 00:03:02 +08:00
config.AppConfig.AsyncCacheTTLHours)
} else {
fmt.Println("异步插件已禁用")
}
2025-07-12 19:53:44 +08:00
// 输出插件信息
fmt.Println("已加载插件:")
for _, p := range pluginManager.GetPlugins() {
fmt.Printf(" - %s (优先级: %d)\n", p.Name(), p.Priority())
}
}