爱意满满的作品展示区。
qvanwu

Node.js 到 Go:夸克资源搜索站(pansou.de)的架构重构实践

  •  
  •   qvanwu · 7h 47m ago · 700 views

    背景

    PanSou 盘搜得 是一个夸克网盘资源聚合搜索平台,上线以来月活用户超过 200 万,索引资源量达 800 万+条。随着用户规模增长,原有的 Node.js 技术栈逐渐暴露出一些问题,最终决定进行一次彻底的架构重构。

    旧架构的痛点

    初版架构采用 Next.js + BullMQ + PostgreSQL + Redis 的组合:

    • Next.js 负责前端渲染和 API Routes
    • BullMQ 处理异步任务(资源转存、定时清理)
    • PostgreSQL 存储资源索引和转存记录
    • Redis 做查询缓存和任务队列

    这套架构在早期运行良好,但随着流量增长,问题逐渐显现:

    1. 并发处理能力受限

    Node.js 单线程模型在高并发场景下压力明显。搜索请求需要调用上游 API 、数据库查询、Redis 缓存,在流量高峰期 P99 响应时间经常突破 2 秒。

    2. 资源占用偏高

    Next.js 进程内存占用大,加上 BullMQ Worker 进程,整体资源消耗不低。在用户量翻倍后,服务器成本压力开始显现。

    3. 维护复杂度上升

    API Routes 、Service 层、Worker 任务散落在不同模块,依赖链路长,排查问题需要跨多个层级。

    4. 定时任务可靠性不足

    BullMQ 虽然成熟,但在资源清理这种长周期任务上偶尔会出现任务堆积,需要人工介入重启。

    重构方案

    核心思路是前后端彻底分离,业务逻辑下沉到性能更强的 Go 服务。

    新架构设计

    用户请求
        ↓
    宝塔 Nginx (反代)
        ↓
    Docker 内部 Nginx
        ├─ /api/v1/*  → Go API (8080)
        └─ /*         → Next.js (3000)
             ↓
        PostgreSQL + Redis
             ↓
        Go Worker (定时清理)
    

    职责划分:

    • Next.js:纯前端渲染 + SSR SEO 落地页,不再承担任何业务逻辑
    • Go API:搜索、转存、账号管理、管理后台所有接口
    • Go Worker:过期资源清理、每日计数重置
    • Nginx:请求路由,未来可扩展灰度发布、限流等能力

    关键技术点

    1. 流式搜索优化
    搜索请求需要调用上游 PanSou API 并实时检测链接有效性。Go 的协程模型天然适合这种场景:

    • 用 Goroutine 并发调用多个上游接口
    • Redis Stream 实现搜索结果的流式推送
    • 检测到 N 条有效链接后提前终止,避免无效等待

    实测搜索 P99 响应时间从 2 秒降到不到 1 秒。

    2. 请求合并防穿透
    热门关键词短时间内可能被重复搜索。通过分布式锁实现请求合并:

    • 相同查询参数的请求只触发一次上游调用
    • 后续请求直接订阅 Redis Stream 获取结果
    • 显著降低了上游 API 压力和缓存穿透风险

    3. 双写模型解决 SEO 问题
    资源转存后生成的落地页对 SEO 至关重要,但分享链接 15 分钟后会过期。采用双写策略:

    • temporary_shares 表:存储短期分享数据( 15 分钟 TTL )
    • resources 表:永久保留 SEO 数据( slug/title/description )
    • Worker 清理时只删网盘文件和临时表,SEO 落地页始终可访问

    用户访问过期资源时显示"资源已过期,请重新搜索",既保留了 SEO 价值,又不影响体验。

    4. 内部网络优化
    Next.js SSR 渲染 SEO 落地页时需要调用 Go API 获取数据。通过 Docker 内网直连:

    // SSR 走内网
    const INTERNAL_API_URL = 'http://go-api:8080';
    

    省去了公网绕行的延迟,SSR 响应速度提升 50-200ms 。

    迁移策略

    采用灰度发布 + 双运行的策略,而非一刀切:

    1. 阶段 1:Go API 上线,Node.js API 继续服务
    2. 阶段 2:通过 Cookie 或 IP 规则切换 10%流量到 Go
    3. 阶段 3:观察监控指标(错误率、响应时间、转存成功率)
    4. 阶段 4:逐步扩大到 50% → 100%
    5. 阶段 5:下线 Node.js API ,清理废弃代码

    全程保留回滚能力,任何阶段出现问题都能快速切回。

    效果

    重构上线后,核心指标全面改善:

    指标 重构前 重构后 提升
    搜索 P99 响应时间 ~2s <1s 50%+
    服务器内存占用 - ↓30%+ 显著降低
    转存成功率 ~90% >95% 更稳定
    并发处理能力 受限 线性扩展 质变

    用户侧感知最明显的是搜索速度和高峰期稳定性。之前晚高峰偶尔会卡顿,现在基本感知不到波动。

    经验总结

    1. 选型要看场景

    Node.js 适合快速迭代和 IO 密集型应用,但在高并发、CPU 密集、长连接场景下,Go 的优势是碾压性的。不是说 Node 不行,而是工具要用对地方。

    2. 灰度发布是刚需

    再有信心的重构也要保留灰度和回滚能力。我们的灰度周期拉了近两周,虽然前期略保守,但确保了零事故上线。

    3. 监控先行

    重构前就部署好 Prometheus + Grafana ,设置好关键指标告警。有数据支撑才能客观评估效果,也能快速定位问题。

    4. 不要动数据模型

    数据层是最难迁移的部分。我们保持了 PostgreSQL 和 Redis 的现有结构,只改了访问层,大大降低了风险。

    写在最后

    这次重构本质上是一次技术债务的集中偿还。旧架构并非不能用,但随着规模增长,边际成本越来越高。与其小修小补,不如趁还有精力时彻底重构。

    对于类似规模的资源站、聚合搜索类项目,如果你也在纠结要不要换技术栈,可以参考这几个信号:

    • P99 响应时间经常超过 2 秒
    • 服务器成本增速超过用户增速
    • 高峰期需要频繁扩容才能撑住
    • 定时任务经常需要人工介入

    如果中了 3 条以上,是时候考虑架构升级了。


    PanSou 盘搜得目前已全面切换到新架构,欢迎体验:
    👉 pansou.de

    免费、无广告、速度快,专注夸克网盘资源搜索。

    6 replies  •  2026-10-11 16:27:22 +08:00
    bbbblue
        1
    bbbblue  
       7h 3m ago
    这结论似乎有点问题?(我不是说 nodejs 性能多好 我就只是说这个结论)
    只能说明 nextjs 做后端是瓶颈 因为你们不是直接用的 nodejs 做后端。。

    如果是 nextjs+nodejs 换成 nextjs+go 的话 这个结论还可以
    jacketma
        2
    jacketma  
       7h 2m ago
    烧了多少 tokes ?🤔
    qvanwu
        3
    qvanwu  
    OP
       6h 20m ago
    @jacketma 差不多 16 亿 Token Opus5.5 ,用的中转站,价格还算能接受
    willygeek007
        4
    willygeek007  
       4h 35m ago via iPhone
    感谢分享
    lizhesystem
        5
    lizhesystem  
       4h 13m ago
    这搜索 速度有点快啊。
    buir9
        6
    buir9  
       2h 24m ago

    哦豁```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2844 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 10:52 · PVG 18:52 · LAX 03:52 · JFK 06:52
    ♥ Do have faith in what you're doing.