CRS 内部控制台

下载器crs.tongsou.com

URL 进,网页对象出。只处理 CSR 页面,拿到 URL 就渲染。

服务边界

CONTRACT.md §一 · 所有对外请求都经过下载器;下载器拉,不被推

⚠️ 采样器与调度器都不直连目标站点。域名限速需要单点保证 —— 新域名首次判定若走直连,是 7 次以上的集中探测,封禁往往就发生在这里。

近 24 小时

来源 downloader:fetch_result:{url_hash} 汇总 · 唯一写入方 下载器

渲染页数
372,140
渲染吞吐
4.3 页/秒
in_flight_count
37
render_duration_ms
780 / P95 2,410
网页库对象数
8,412,663
网页库占用
641 GB

⚠️ 瓶颈在渲染 CPU,不在队列供给。当前 4 核,理论上限 3~5 页/秒;扩容加机器即可,每台用不同 worker_id 去 lease,调度器自动分配。max_concurrent_count 是唯一的成本刹车。

三个入口

DEV-downloader-v1.md §三 · 入口 A、B 写入同一网页库,入口 C 不入库

入口路径模式入库限速行为24h 调用状态
A · lease 循环 GET scheduling-url/v1/lease 批量异步 超限延迟执行 365,222 运行中
B · 取页 POST /v1/render 同步依 should_store 超限返回 429 + retry_after_seconds 6,918 运行中
C · 健康探针 POST /v1/probe 同步 超限返回 has_reached_origin = false 12,405 运行中

⚠️ 入口 B、C 不经过调度器的出队路径,本服务的域名限速不是重复限速,是堵住这条绕过路径。downloader:domain_runtimescheduler:domain_runtime 是两个独立计数器,故意重复,不同步。

⚠️ 入口 C 内部强制 should_store = false,且只返回精简结构 —— 返回完整网页对象会把调度器与网页对象 schema 绑死。

抓取结果分布

downloader:fetch_result:{url_hash} · fetch_status 四值,与调度器的 schedule_status 是两套枚举

fetch_status页数占比占比含义
done318,90485.7% 渲染成功,对象已落库
not_modified24,1906.5% 条件请求命中 304,跳过渲染,统计字段全为 null
empty21,5885.8% 渲染成功但正文为空,对象已落库,下游扫描应跳过
failed7,4582.0% 渲染失败,无对象

⚠️ empty 独立于 failednot_modified 独立于 done。四值合并任意两个,下游会消费到空壳,调度器会把 304 当成 text_length 骤降并触发误报复核。

失败率 2.0% —— 按 DEV-downloader-v2.md §三,低于 5% 不做 Chrome 兜底,渲染失败 report failed 即可。该结论以门槛二的完整数据为准。

最近抓取

网页对象摘要 + 随 report 回传的 health_signal · 完整对象见网页库

urlhttp_statusfetch_status render_duration_msraw_text_lengthtext_length xhr_error / totalhas_console_errorobject_id
https://news.example.tw/post/48213 200done812 1803,4560 / 12 false7f2a9c…
https://docs.example.cn/guide/5 200done640 2105,1200 / 9 falseb1d40e…
https://shop.example.jp/item/9910 200empty1,940 9603 / 18 true2c77af…
https://blog.example.com/p/771 304not_modified nullnullnull nullnullnull
https://m.example.hk/article/22 502failed nullnullnull nullnullnull

⚠️ not_modifiedfailed 两行的 health_signal 整体为 null,不是零。把 null 当成「零个错误 XHR」,会把一个后端全挂的域名判成健康。

域名限速

downloader:domain_runtime:{domain} · 唯一写入方 下载器 · 与调度器的同名表不同步

domainmin_interval_ms来源last_request_atin_flight_count状态
news.example.tw1,000lease 消息2026-08-15T07:47:52Z3正常
shop.example.jp2,000lease 消息2026-08-15T07:47:51Z1正常
docs.example.cn1,000lease 消息2026-08-15T07:47:49Z2正常
blog.example.com1,000全局默认2026-08-15T07:47:44Z0入口 B 超限

⚠️ min_interval_ms 由采样器算好(已取 crawl_delay 与语种默认值的较大者),本服务直接用,禁止再取一次 max。入口 B 无此值时才落到全局默认。

上线门槛

DEV-downloader-v1.md §九 · 两项都未通过前不进入正式抓取

门槛验证内容通过判据状态
一 · Obscura 懒加载 四语种各 5 个已知懒加载站,比对 Obscura 与 Chrome 的正文字数与列表页链接数 差距 < 5% 按现方案开发;> 10% 则 v1 就要接 Stylo 或改 Chrome 待验证
二 · 渲染稳定性 四语种各 50 个已知 CSR 页面连续渲染 4 小时,记内存曲线、失败率与类型分布、P50 / P95 失败率数据决定 v2 要不要做 Chrome 兜底 进行中

⚠️ 门槛一的第 3 项最关键:正文残缺只影响单页,列表残缺影响整棵子树的链接图谱。它同时决定吞吐系数 —— 若要接 Stylo 或改 Chrome,同样核数的吞吐降三到四成。