电子书模板中心
海外站日访问约 1500 万 · 峰值 QPS 1000+ · 服务端处理仅 80-120ms · 模板 3000+ · 28 语言
背景与结果
电子书(翻页画册/杂志)产品的模板中心:用户按 7 个维度(语言/等级/分类/排序/主题/颜色/风格)浏览筛选模板、预览、套模板创建作品。双站点同一套设计实现——海外站与国内站功能类似、访问量级不同。
2025.06 至约 2026.03(约 9 个月上线),一人独立负责双站点从前端页面、服务端到管理后台的整体设计与实现。部署从 1 实例扩到 3 实例,代码零改动。
核心挑战:模板链接由 7 个维度组成——语言 28 × 等级 4 × 分类 30 × 排序 3 × 主题 120 × 颜色 65 × 风格 70,排列组合约 55 亿 URL(有效 URL 约 100 来万)。海量长尾组合导致 CDN 命中率趋近于零,且数据动态(浏览数/使用数/排序实时变)+ 支持模糊搜索——所有流量必须回源、在源站消化。海外站模板页日访问约 1500 万(90% 集中在 4-5 小时,归因爬虫不规范爬取),峰值 QPS 一千出头,总响应 300-400ms 中服务端仅占 80-120ms。
技术方案
四级请求处理链路(核心)
请求 → [L1 内存路由字典校验] --非法拼接→ 直接 404(不碰任何存储,~1ms)
→ [L2 ES 查询 10-20ms](match + function_score 自定义评分)
→ [L3 本地 Guava 多语言标签缓存](容量 + 过期可配)
→ [L4 stale-while-revalidate:先返旧值 + 子线程抢分布式锁异步刷新]
→ 响应(服务端共 80-120ms)
L1 路由字典:各维度所有合法取值组成路由字典存内存。请求先解析路径中的过滤规则,不在字典内的(爬虫拼凑的非法链接)直接 404——把非法流量挡在碰任何存储之前,校验成本仅一次内存查找(~1ms)。高峰期大量请求是不规范路由链接,被此层消化。
L2 ES 查询:汇总分类条件查 ES(10-20ms)。搜索是混合方案:维度条件 match 查询 + 自定义加分/减分评分脚本(function_score)调排序权重,实现运营侧推荐调控。数据量 3000+,脚本无性能问题。
L3 多语言标签组装:ES 结果不能直接返回——28 种语言下同一维度表达不同,需查每个模板的多语言标签。基于 Guava Cache 实现:最大缓存数量 + 过期时间均可配,框架级淘汰;每个模板一个 Map(key=语言,value=该语言下维度信息),另一个 Map 记录缓存时间,职责分离。
L4 stale-while-revalidate:读取时发现缓存超过 10 分钟 → 先返回旧数据(用户无感),同时子线程抢分布式锁读最新数据回填——锁保证多实例下同一模板不被并发重复刷新(防 dogpile 击穿)。10 分钟 TTL 替代主动失效机制:后台改动最长 10 分钟生效,不需要额外的失效链路;可用性与新鲜度解耦。
动态计数(浏览数/使用数)
每次浏览/套用对 Redis INCR 自增,不做 DB 实时写;定时脚本每小时算增量(对比上次入库值的差值)写回 DB——非清零方式,天然避免"清零瞬间新自增丢失"的竞态,脚本延迟也不丢数据(累计值在 Redis,最终都能入库)。高频计数只碰 Redis(O(1)),DB 每小时批量落一次,读写压力解耦。
ES 数据同步(双保险)
每条模板记录有"最后推送 ES 时间"字段,每次推送刷新。修改时实时推送 + 定时脚本每小时扫描超 1 小时未同步的数据补偿——实时链路漏掉的由兜底扫描补齐,保证最终一致。
AI 提取(上线后小迭代)
给 ChatGPT API 提供模板内容(文字描述 + 图片),提取 7 类信息——维度类(风格/分类/主题/颜色,自动打标)+ 内容类(话题/标题/描述/关键字,SEO 与展示文案)。
人机协同流程:AI 提取结果不直接入库,先渲染成界面给管理员校验修改,确认后才保存——"AI 生产 + 人工把关"两段式,数据质量由人兜底。
Prompt 与代码解耦:prompt 是独立文件,由模板管理员维护——调提示词不用改代码发版。
成本:单模板一次提取约 1 元多,3000+ 模板全量打标几千元;人工逐模板打标写文案要十几分钟,AI 秒级出草稿。
迭代与取舍
- 单机起步、按锁扩展:全链路按多实例设计(分布式锁、无本地状态依赖),1 实例扛住上线,流量上来后扩到 3 实例零代码改动
- 缓存新鲜度换简单性:主动失效需要打通"后台改动 → 广播失效"链路,引入额外组件与故障面;10 分钟 TTL + SWR 用最长 10 分钟的数据延迟换来整条失效链路的省略,对模板文案这种非关键数据是划算的取舍
- sitemap 是计算密集任务:55 亿组合中算出有效 URL 集,开多台机器并行跑出来的