独立开发者:自建流量监控系统 pvuv.ai 部署复盘
开源仓库:github.com/qiayue/pvuv.ai(MIT)
自建控制台:analytics.example.com· 采集端:in.example.com· 埋点脚本:f.js
部署环境:自有 Cloudflare 账号 · 登录方式:Google OAuth · 接入规模:约 76 个站点
时间:2026-10-31(Asia/Shanghai)
本文是对开源项目 pvuv.ai 进行完整自建部署的实战复盘。核心目标是将流量数据完全托管于自有 Cloudflare 账号,并将「流量质量甄别」与「广告防护」作为系统的一等公民,从架构层面解决 Bot 过滤与无效流量问题。
1. 为何选择自建
面对视频梗站、AI 工具站等混合站点矩阵,继续依赖第三方托管统计存在以下长期痛点:
隐私与数据归属权
自建后,访客行为、来源追踪(UTM)、会话链路等核心数据均存储于自有 Cloudflare D1/KV/Queues 中,彻底脱离第三方分析服务的数据掌控。流量质量为核心指标
传统自托管脚本往往仅统计请求数,导致真人、可疑用户、机器人与爬虫数据混杂。pvuv 从设计之初即将真实性打分(正常/可疑/机器人/爬虫)集成至主面板,提供精准的用户画像。广告收益防护
对于依靠广告变现的站点,无效流量不仅污染数据,更可能危及广告账户安全。pvuv 支持按档位估算拦截影响,并允许仅对可信流量注入广告代码(默认 fail-open 策略,优先保障收入,避免误伤)。运维模型高度匹配
基于现有的 Cloudflare Workers 技术栈,新增一套 Workers + D1 的统计系统无需额外维护服务器或外部数据库,运维成本极低。
虽然 pvuv.ai 托管版体验良好,但为了实现数据主权与策略自主,自建成为更优选择。
2. 系统架构与域名规划
参照开源 README,我们将链路映射至自有域名,技术栈保持与上游一致:Workers(负责 ingest/consumer/api/console/cron)、D1(按月分表存储事件)、Queues(削峰填谷)、KV(黑名单与配置缓存)及 Cron Triggers。
浏览器 (f.js)
→ in.example.com (Ingest Worker):校验 + 服务端补全 + 实时打分
→ Cloudflare Queue
→ Consumer Worker:批量写入 D1 events,更新 sessions / 用户画像
→ Cron(每小时):rollup 预聚合
→ Cron(每天):群体分析 → 重新判定 + 更新 KV 黑名单
→ analytics.example.com (控制台):展示看板、流量质量、CWV、广告防护数据
域名职责划分:
| 角色 | 域名示例 |
|---|---|
| 控制台(看板/登录) | analytics.example.com |
| 采集 / 判定(Ingest) | in.example.com |
| 埋点脚本 | f.js(需确保嵌入时 data-api 指向自家 Ingest 域名) |
关键配置提醒:站点嵌入代码中的 data-api 必须明确指向 https://in.example.com。SDK 内置默认值为参考域名,若不修改会导致数据错误发送至他人服务器。
控制台核心功能:
- 站点网格:按浏览量(PV)排序,直接展示真人比例。
- 主题切换:支持浅色/深色模式。
- 单站概览:涵盖访客、会话、跳出率、真人占比及异常色带警示。
- Core Web Vitals (CWV):监控 LCP / INP / CLS / FCP / TTFB 的 p75 值。
- 流量质量与广告防护:环图展示流量构成,表格预估不同拦截档位(平衡/激进/最严格的影响)。
3. 部署踩坑指南
3.1 Google OAuth 与用户唯一性冲突
控制台采用 Google OAuth 登录,D1 users 表中 email 字段设为 UNIQUE。由于自建版为单租户模式,所有管理员邮箱登录后均映射至内部 owner id(源码固定为 admin)。
问题现象:若早期种子数据将邮箱字符串直接作为 user_id,后续 OAuth 回调尝试插入 user_id = admin 且携带同一邮箱时,会因 email UNIQUE 约束冲突导致登录失败(返回 500 错误)。
解决方案:参考开源代码 resolveUser 逻辑: 1. 查询同一邮箱但 user_id 非 admin 的旧记录; 2. 将该旧 ID 名下的 sites.owner_id 和 api_tokens.owner_id 迁移至 admin; 3. 删除旧用户记录,并对 admin 执行 ON CONFLICT(user_id) upsert 操作以更新邮箱等信息。
同时,需确保 Google OAuth 回调地址正确指向 https://analytics.example.com/api/auth/google/callback,并在环境变量 ADMIN_EMAILS 中配置真实管理员邮箱。
3.2 自检时误用错误的 Ingest 主机名
常见误区:误以为采集端域名为 in.analytics... 等拼接形式。
正确配置:采集主机应严格对应部署时绑定的自定义域名,即 in.example.com。控制台域名 analytics.example.com 仅负责展示与鉴权,不接收 Beacon 数据。若混用,将导致页面访问正常但自检无数据的情况。
4. 实施效果
- 接入规模:已完成约 76 个站点的嵌入与注册。
- 管理效率:站点卡片按 PV 排序,直观展示会话数与真人比例,便于快速扫描矩阵状态。
- 流量透视:可细分查看正常、可疑、机器人及爬虫流量。拦截档位表能量化评估不同策略下的流量损失与误伤上限。
- CWV 性能旁证:以站点 A 为例,通过自建数据监控,LCP p75 从早期的 7.5s+(较差)优化收敛至 3.15s(需改进)。统计系统虽不直接优化页面,但提供了统一的数据视角来追踪性能变化,无需依赖第三方 RUM 服务。
以下为控制台实机截图(深色主题模式):
5. 小结与复用清单
- 确认 Cloudflare 域名 DNS 已托管,并订阅支持 Queues 的 Workers 付费套餐。
- 遵循上游
DEPLOY.zh-CN.md文档,通过npm run setup初始化 Worker、D1、KV、Queue 及自定义域。 - 配置 OAuth 回调地址及
ADMIN_EMAILS;注意处理users.email唯一性约束与单租户adminID 的数据迁移。 - 所有嵌入代码与自检流程务必指向
in.example.com,避免使用臆造的子域名。 - 上线初期建议先观察流量质量与广告防护的「影子/估算」模式,确认无误后再调整实际拦截档位。
开源地址:https://github.com/qiayue/pvuv.ai
(注:本文不涉及任何敏感凭证如 Token、OAuth Client Secret 等。)

