Files
pansou/docs/系统开发设计文档.md
2025-08-01 21:21:42 +08:00

18 KiB
Raw Blame History

PanSou 网盘搜索系统开发设计文档

📋 文档目录


1. 项目概述

1.1 项目定位

PanSou是一个高性能的网盘资源搜索API服务支持TG搜索和自定义插件搜索。系统采用异步插件架构具备二级缓存机制和并发控制能力在MacBook Pro 8GB上能够支持500用户并发访问。

1.2 性能表现(实测数据)

  • 500用户瞬时并发: 100%成功率平均响应167ms
  • 200用户持续并发: 30秒内处理4725请求QPS=148
  • 缓存命中: 99.8%请求<100ms响应时间
  • 高可用性: 长时间运行无故障

1.3 核心特性

  • 异步插件系统: 双级超时控制4秒/30秒渐进式结果返回
  • 二级缓存系统: 分片内存缓存+分片磁盘缓存GOB序列化
  • 工作池管理: 基于util/pool的并发控制
  • 智能结果合并: mergeSearchResults函数实现去重合并
  • 多维度排序: 插件等级+时间新鲜度+优先关键词综合评分
  • 多网盘类型支持: 自动识别12种网盘类型

2. 系统架构设计

2.1 整体架构流程

graph TB
    A[用户请求] --> B{API网关<br/>中间件}
    B --> C[参数解析<br/>与验证]
    C --> D[搜索服务<br/>SearchService]
    
    D --> E{数据来源<br/>选择}
    E -->|TG| F[Telegram搜索]
    E -->|Plugin| G[插件搜索]
    E -->|All| H[并发搜索]
    
    H --> F
    H --> G
    
    F --> I[TG频道搜索]
    I --> J[HTML解析]
    J --> K[链接提取]
    K --> L[结果标准化]
    
    G --> M[插件管理器<br/>PluginManager]
    M --> N[异步插件调度]
    N --> O[插件工作池]
    O --> P[HTTP客户端]
    P --> Q[目标网站API]
    Q --> R[响应解析]
    R --> S[结果过滤]
    
    L --> T{二级缓存系统}
    S --> T
    
    T --> U[分片内存缓存<br/>LRU + 原子操作]
    T --> V[分片磁盘缓存<br/>GOB序列化]
    
    U --> W[缓存检查]
    V --> W
    W --> X{缓存命中?}
    
    X -->|是| Y[缓存反序列化]
    X -->|否| Z[执行搜索]
    
    Z --> AA[异步更新缓存]
    AA --> U
    AA --> V
    
    Y --> BB[结果合并<br/>mergeSearchResults]
    AA --> BB
    
    BB --> CC[网盘类型分类]
    CC --> DD[智能排序算法<br/>插件等级+时间+关键词]
    DD --> EE[结果过滤<br/>cloud_types]
    EE --> FF[JSON响应]
    FF --> GG[用户]
    
    %% 异步处理流程
    N --> HH[短超时处理<br/>4秒]
    HH --> II{是否完成?}
    II -->|是| JJ[返回完整结果<br/>isFinal=true]
    II -->|否| KK[返回部分结果<br/>isFinal=false]
    
    KK --> LL[后台继续处理<br/>最长30秒]
    LL --> MM[完整结果获取]
    MM --> NN[主缓存更新]
    NN --> U
    
    %% 样式定义
    classDef cacheNode fill:#e1f5fe
    classDef pluginNode fill:#f3e5f5
    classDef searchNode fill:#e8f5e8
    classDef asyncNode fill:#fff3e0
    
    class T,U,V,W,X,Y,AA cacheNode
    class M,N,O,P,G pluginNode
    class F,I,J,K,L searchNode
    class HH,II,JJ,KK,LL,MM,NN asyncNode

2.2 异步插件工作流程

sequenceDiagram
    participant U as 用户
    participant API as API Gateway
    participant S as SearchService  
    participant PM as PluginManager
    participant P as AsyncPlugin
    participant WP as WorkerPool
    participant C as Cache
    participant EXT as 外部API

    U->>API: 搜索请求 (kw=关键词)
    API->>S: 处理搜索
    S->>C: 检查缓存
    
    alt 缓存命中
        C-->>S: 返回缓存数据 (<100ms)
        S-->>U: 返回结果
    else 缓存未命中
        S->>PM: 调度插件搜索
        PM->>P: 设置关键词和缓存键
        P->>WP: 提交异步任务
        
        par 短超时处理 (4秒)
            WP->>EXT: HTTP请求
            EXT-->>WP: 响应数据
            WP->>P: 解析结果
            P-->>S: 部分结果 (isFinal=false)
            S->>C: 缓存部分结果
            S-->>U: 快速响应
        and 后台完整处理 (最长30秒)
            WP->>EXT: 继续处理
            EXT-->>WP: 完整数据
            WP->>P: 完整结果
            P->>S: 最终结果 (isFinal=true)
            S->>C: 更新主缓存
            Note over C: 用户下次请求将获得完整结果
        end
    end

2.3 核心组件

2.3.1 HTTP服务层 (api/)

  • router.go: 路由配置
  • handler.go: 请求处理逻辑
  • middleware.go: 中间件日志、CORS等

2.3.2 搜索服务层 (service/)

  • search_service.go: 核心搜索逻辑,结果合并

2.3.3 插件系统层 (plugin/)

  • plugin.go: 插件接口定义
  • baseasyncplugin.go: 异步插件基类
  • 各插件目录: jikepan、pan666、hunhepan等

2.3.4 工具层 (util/)

  • cache/: 二级缓存系统实现
  • pool/: 工作池实现
  • 其他工具: HTTP客户端、解析工具等

3. 异步插件系统

3.1 设计理念

异步插件系统解决传统同步搜索响应慢的问题,采用"尽快响应,持续处理"策略:

  • 4秒短超时: 快速返回部分结果(isFinal=false
  • 30秒长超时: 后台继续处理,获得完整结果(isFinal=true
  • 主动缓存更新: 完整结果自动更新主缓存,下次访问更快

3.2 插件接口实现

基于plugin/plugin.go的实际接口:

type AsyncSearchPlugin interface {
    Name() string
    Priority() int
    
    AsyncSearch(keyword string, searchFunc func(*http.Client, string, map[string]interface{}) ([]model.SearchResult, error), 
               mainCacheKey string, ext map[string]interface{}) ([]model.SearchResult, error)
    
    SetMainCacheKey(key string)
    SetCurrentKeyword(keyword string)
    Search(keyword string, ext map[string]interface{}) ([]model.SearchResult, error)
}

3.3 基础插件类

plugin/baseasyncplugin.go提供通用功能:

type BaseAsyncPlugin struct {
    name              string
    priority          int
    cacheTTL          time.Duration
    mainCacheKey      string
    currentKeyword    string        // 用于日志显示
    httpClient        *http.Client
    mainCacheUpdater  func(string, []model.SearchResult, time.Duration, bool, string) error
}

3.4 已实现插件列表

当前系统包含以下插件(基于main.go的导入):

  • hdr4k
  • hunhepan
  • jikepan
  • pan666
  • pansearch
  • panta
  • qupansou
  • susu
  • panyq
  • xuexizhinan

3.5 插件注册机制

// 全局插件注册表plugin/plugin.go
var globalRegistry = make(map[string]AsyncSearchPlugin)

// 插件通过init()函数自动注册
func init() {
    p := &MyPlugin{
        BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("myplugin", 3),
    }
    plugin.RegisterGlobalPlugin(p)
}

4. 二级缓存系统

4.1 实现架构

基于util/cache/目录的实际实现:

  • enhanced_two_level_cache.go: 二级缓存主入口
  • sharded_memory_cache.go: 分片内存缓存LRU+原子操作)
  • sharded_disk_cache.go: 分片磁盘缓存
  • serializer.go: GOB序列化器
  • cache_key.go: 缓存键生成和管理

4.2 分片缓存设计

4.2.1 内存缓存分片

// 基于CPU核心数的动态分片
type ShardedMemoryCache struct {
    shards    []*MemoryCacheShard
    shardMask uint32
}

// 每个分片独立锁,减少竞争
type MemoryCacheShard struct {
    data map[string]*CacheItem
    lock sync.RWMutex
}

4.2.2 磁盘缓存分片

// 磁盘缓存同样采用分片设计
type ShardedDiskCache struct {
    shards    []*DiskCacheShard  
    shardMask uint32
    basePath  string
}

4.3 缓存读写策略

4.3.1 读取流程

  1. 内存优先: 先检查分片内存缓存
  2. 磁盘回源: 内存未命中时读取磁盘缓存
  3. 异步加载: 磁盘命中后异步加载到内存

4.3.2 写入流程

  1. 双写模式: 同时写入内存和磁盘
  2. 原子操作: 内存缓存使用原子操作
  3. GOB序列化: 磁盘存储使用GOB格式

4.4 缓存键策略

cache_key.go实现了智能缓存键生成:

// TG搜索和插件搜索使用不同的缓存键前缀
func GenerateTGCacheKey(keyword string, channels []string) string
func GeneratePluginCacheKey(keyword string, plugins []string) string

优势:

  • 独立更新TG和插件缓存互不影响
  • 提高命中率:精确的键匹配
  • 并发安全:分片设计减少锁竞争

4.5 序列化性能

使用GOB序列化serializer.go)的实际优势:

  • 性能: 比JSON序列化快约30%
  • 体积: 比JSON小约20%
  • 兼容: Go原生支持无外部依赖

5. 核心组件实现

5.1 工作池系统 (util/pool/)

5.1.1 worker_pool.go 实现

  • 批量任务处理: ExecuteBatchWithTimeout方法
  • 超时控制: 支持任务级别的超时设置
  • 并发限制: 控制最大工作者数量

5.1.2 object_pool.go 实现

  • 对象复用: 减少内存分配和GC压力
  • 线程安全: 支持并发访问

5.2 HTTP服务配置

5.2.1 服务器优化基于config/config.go

// 自动计算HTTP连接数防止资源耗尽
func getHTTPMaxConns() int {
    cpuCount := runtime.NumCPU()
    maxConns := cpuCount * 25  // 保守配置
    
    if maxConns < 100 {
        maxConns = 100
    }
    if maxConns > 500 {
        maxConns = 500  // 限制最大值
    }
    
    return maxConns
}

5.2.2 连接池配置基于util/http_util.go

// HTTP客户端优化配置
transport := &http.Transport{
    MaxIdleConns:        100,
    MaxIdleConnsPerHost: 10,
    IdleConnTimeout:     90 * time.Second,
}

5.3 结果处理系统

5.3.1 智能排序算法service/search_service.go

PanSou 采用多维度综合评分排序算法,确保高质量结果优先展示:

评分公式:

总得分 = 插件得分(1000/500/0/-200) + 时间得分(最高500) + 关键词得分(最高420)

权重分配:

  • 🥇 插件等级: ~52% (主导因素) - 等级1(1000分) > 等级2(500分) > 等级3(0分)
  • 🥈 关键词匹配: ~22% (重要因素) - "合集"(420分) > "系列"(350分) > "全"(280分)
  • 🥉 时间新鲜度: ~26% (重要因素) - 1天内(500分) > 3天内(400分) > 1周内(300分)

关键优化:

  • 缓存性能: 跳过空结果和重复数据的缓存更新减少70%无效操作
  • 排序稳定性: 修复map遍历随机性问题确保merged_by_type保持排序
  • 插件管理: 启动时按优先级排序显示已加载插件,便于监控

5.3.2 结果合并mergeSearchResults函数

  • 去重合并: 基于UniqueID去重
  • 完整性选择: 选择更完整的结果保留
  • 增量更新: 新结果与缓存结果智能合并

5.4 网盘类型识别

支持自动识别的网盘类型共12种

  • 百度网盘、阿里云盘、夸克网盘、天翼云盘
  • UC网盘、移动云盘、115网盘、PikPak
  • 迅雷网盘、123网盘、磁力链接、电驴链接

6. 智能排序算法详解

6.1 算法概述

PanSou 搜索引擎采用多维度综合评分排序算法,确保用户能够优先看到最相关、最新、最高质量的搜索结果。

6.1.1 核心设计理念

  1. 质量优先:高等级插件的结果优先展示
  2. 时效性重要:新发布的资源获得更高权重
  3. 相关性保证:关键词匹配度影响排序
  4. 用户体验:最终排序结果保持稳定性

6.1.2 排序流程

graph TD
    A[搜索请求] --> B[获取搜索结果 allResults]
    B --> C[sortResultsByTimeAndKeywords]
    
    C --> D[为每个结果计算得分]
    D --> E[时间得分<br/>最高500分]
    D --> F[关键词得分<br/>最高420分]
    D --> G[插件得分<br/>等级1=1000分<br/>等级2=500分<br/>等级3=0分]
    
    E --> H[总得分 = 时间得分 + 关键词得分 + 插件得分]
    F --> H
    G --> H
    
    H --> I[按总得分降序排序]
    I --> J[mergeResultsByType]
    
    J --> K[按原始顺序收集唯一链接<br/>保持排序不被破坏]
    K --> L[按类型分组<br/>生成merged_by_type]
    
    L --> M[返回最终结果]

6.2 评分算法详解

6.2.1 核心公式

总得分 = 时间得分 + 关键词得分 + 插件得分

6.2.2 时间得分 (Time Score)

时间得分反映资源的新鲜度,最高 500 分

时间范围 得分 说明
≤ 1天 500 最新资源,最高优先级
≤ 3天 400 非常新的资源
≤ 1周 300 较新资源
≤ 1月 200 相对较新
≤ 3月 100 中等新鲜度
≤ 1年 50 较旧资源
> 1年 20 旧资源
无日期 0 未知时间

6.2.3 关键词得分 (Keyword Score)

关键词得分基于搜索词在标题中的匹配情况,最高 420 分

优先关键词 得分 说明
"合集" 420 最高优先级
"系列" 350 高优先级
"全" 280 中高优先级
"完" 210 中等优先级
"最新" 140 较低优先级
"附" 70 低优先级
无匹配 0 无加分

6.2.4 插件得分 (Plugin Score)

插件得分基于数据源的质量等级,体现资源可靠性:

插件等级 得分 说明
等级1 1000 顶级数据源
等级2 500 优质数据源
等级3 0 普通数据源
等级4 -200 低质量数据源

6.3 权重分析与实际效果

6.3.1 权重分配

维度 最高分值 权重占比 影响说明
插件等级 1000 ~52% 主导因素,决定基础排序
关键词匹配 420 ~22% 重要因素,优先关键词显著加分
时间新鲜度 500 ~26% 重要因素,同等级内排序关键

6.3.2 实际排序示例

场景 插件等级 时间 关键词 总分 排序
等级1 + 1天内 + "合集" 1000 500 420 1920 🥇 第1
等级1 + 1天内 + "系列" 1000 500 350 1850 🥈 第2
等级1 + 1月内 + "合集" 1000 200 420 1620 🥉 第3
等级2 + 1天内 + "合集" 500 500 420 1420 第4
等级1 + 1天内 + 无关键词 1000 500 0 1500 第5

7. API接口设计

7.1 核心接口实现基于api/handler.go

7.1.1 搜索接口

POST /api/search
GET  /api/search

核心参数:

  • kw: 搜索关键词(必填)
  • channels: TG频道列表
  • plugins: 插件列表
  • cloud_types: 网盘类型过滤
  • ext: 扩展参数JSON格式
  • refresh: 强制刷新缓存
  • res: 返回格式merge/all/results
  • src: 数据源all/tg/plugin

7.1.2 健康检查接口

GET /api/health

返回系统状态和已注册插件信息。

6.2 中间件系统api/middleware.go

  • 日志中间件: 记录请求响应支持URL解码显示
  • CORS中间件: 跨域请求支持
  • 错误处理: 统一错误响应格式

6.3 扩展参数系统

通过ext参数支持插件特定选项:

{
  "title_en": "English Title",
  "is_all": true,
  "year": 2023
}

8. 插件开发框架

8.1 基础开发模板

package myplugin

import (
    "net/http"
    "pansou/model"
    "pansou/plugin"
)

type MyPlugin struct {
    *plugin.BaseAsyncPlugin
}

func init() {
    p := &MyPlugin{
        BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("myplugin", 3),
    }
    plugin.RegisterGlobalPlugin(p)
}

func (p *MyPlugin) Search(keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
    return p.AsyncSearch(keyword, p.searchImpl, p.GetMainCacheKey(), ext)
}

func (p *MyPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
    // 实现具体搜索逻辑
    // 1. 构建请求URL
    // 2. 发送HTTP请求  
    // 3. 解析响应数据
    // 4. 转换为标准格式
    // 5. 关键词过滤
    return plugin.FilterResultsByKeyword(results, keyword), nil
}

8.2 插件注册流程

  1. 自动注册: 通过init()函数自动注册到全局注册表
  2. 管理器加载: PluginManager统一管理所有插件
  3. 导入触发: 在main.go中通过空导入触发注册

8.3 开发最佳实践

  • 命名规范: 插件名使用小写字母
  • 优先级设置: 1-5数字越小优先级越高
  • 错误处理: 详细错误信息,便于调试
  • 资源管理: 及时释放HTTP连接

9. 性能优化实现

9.1 环境配置优化

基于实际性能测试结果的配置方案:

9.1.1 macOS优化配置

export HTTP_MAX_CONNS=200
export ASYNC_MAX_BACKGROUND_WORKERS=15
export ASYNC_MAX_BACKGROUND_TASKS=75
export CONCURRENCY=30

9.1.2 服务器优化配置

export HTTP_MAX_CONNS=500
export ASYNC_MAX_BACKGROUND_WORKERS=40
export ASYNC_MAX_BACKGROUND_TASKS=200
export CONCURRENCY=50

9.2 日志控制系统

基于config.go的日志控制:

export ASYNC_LOG_ENABLED=false  # 控制异步插件详细日志

异步插件缓存更新日志可通过环境变量开关,避免生产环境日志过多。


10. 技术选型说明

10.1 Go语言优势

  • 并发支持: 原生goroutine适合高并发场景
  • 性能优秀: 编译型语言接近C的性能
  • 部署简单: 单一可执行文件,无外部依赖
  • 标准库丰富: HTTP、JSON、并发原语完备

10.2 GIN框架选择

  • 高性能: 路由和中间件处理效率高
  • 简洁易用: API设计简洁学习成本低
  • 中间件生态: 丰富的中间件支持
  • 社区活跃: 文档完善,问题解决快

10.3 GOB序列化选择

  • 性能优势: 比JSON快约30%
  • 体积优势: 比JSON小约20%
  • Go原生: 无需第三方依赖
  • 类型安全: 保持Go类型信息

10.4 无数据库架构

  • 简化部署: 无需数据库安装配置
  • 降低复杂度: 减少组件依赖
  • 提升性能: 避免数据库IO瓶颈
  • 易于扩展: 无状态设计,支持水平扩展