LeetCode Hot100 在线人数看板

最近每天都会做几道LeetCode Hot100题,突发奇想,使用AI做一个采集数据并展示出来的小功能,看一下哪些题目刷的人比较多(毫无疑问,two-sum一直稳居榜首),最终的页面能够实时看到在线人数前十的题目,并且能够看到每一道题最近7天的在线人数变化趋势。整个项目涉及数据采集、API 服务、存储和前端展示四个部分,分别部署在 Railway、Cloudflare Workers、Cloudflare KV/D1 和 Vercel 上。

由于使用的是cloudflare的免费额度,KV写入读取有限制,所以采集数据采取每2分钟上报一次,这样每天就只有720次写入,不超过免费额度。D1的写入读取也有相应的优化来满足要求。

整体架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────┐    WebSocket     ┌──────────────┐    Push API    ┌─────────────────────┐
│ LeetCode │ ◄──────────────► │ Railway │ ─────────────► │ Cloudflare Workers │
│ (数据源) │ │ (采集脚本) │ │ (API 服务) │
└─────────────┘ └──────────────┘ └──────────┬──────────┘

┌──────┴──────┐
│ │
┌────▼───┐ ┌────▼───┐
│ KV │ │ D1 │
│ (汇总) │ │ (明细) │
└────────┘ └────────┘
│ │
└──────┬──────┘

┌────────▼────────┐
│ Vercel │
│ (前端看板页面) │
└─────────────────┘

整个数据流向:采集脚本通过 WebSocket 连接 LeetCode 获hot100在线人数数据,调用 Cloudflare Workers 的 Push 接口写入存储,前端页面从 Workers 读取数据并展示。

数据采集 — Railway

采集脚本部署在 Railway 上,通过 LeetCode 的 WebSocket 接口实时获取在线人数数据。选择 WebSocket 而不是传统的 HTTP 轮询,主要是因为可以实时拿到在线人数数据,减少不必要的请求。

Railway 作为采集服务的运行平台,优势在于:

  • 支持持久运行的后台进程,适合维持 WebSocket 长连接
  • 部署简单,直接关联 Git 仓库即可自动部署
  • 有免费额度,对于这种轻量采集任务完全够用

采集脚本拿到数据后,通过 HTTP 请求调用 Cloudflare Workers 提供的 Push 接口上传数据。

API 服务与存储 — Cloudflare Workers + KV + D1

Cloudflare Workers 负责提供 API 服务,主要包含两个功能:

  1. Push 接口:接收采集脚本上传的数据,写入 KV 和 D1
  2. Query 接口:供前端页面查询在线人数数据

存储层采用 KV 和 D1 配合使用,各有分工:

KV(汇总数据):存储聚合后的统计信息,比如最新的100道题的在线人数。KV 的读取速度极快,非常适合这种高频读取、低频写入的汇总数据。

D1(明细数据):存储每道题目每个时刻的在线人数。D1 是 Cloudflare 的 SQLite 数据库,支持 SQL 查询,适合按条件筛选和排序题目列表。

这种分层存储的设计思路是:前端加载看板时,先从 KV 读取最新数据来渲染盘行榜,需要查看具体题目的在线人数历史数据时候再查询D1数据库。保证页面加载速度。

前端看板 — Vercel

前端使用纯 HTML/CSS/JavaScript 实现,没有引入框架,保持轻量。部署在 Vercel 上,访问地址:https://hot100-dashboard.vercel.app/

页面主要展示:

  • 在线人数前十的题
  • hot100的所有题目
  • 每道题历史7天在线人数折线图

选择 Vercel 部署纯静态页面的原因很简单:零配置、自动 HTTPS、全球 CDN、部署速度快。

为什么选择这套架构

这套架构的核心思路是把不同职责分散到最适合的平台上

组件 平台 原因
数据采集 Railway 需要持久运行的后台进程
API + 存储 Cloudflare Workers 冷启动快,KV/D1 与 Workers 无缝集成
前端展示 Vercel 静态站点部署体验好

每个服务都有免费额度,整套方案的运行成本为零。同时各组件之间通过 HTTP 接口通信,耦合度低,任何一部分都可以单独替换。

小结

这个项目虽然功能不复杂,但涉及到数据采集、API 设计、存储选型、前端展示等多个环节,是一个比较完整的全栈小项目。Cloudflare Workers + KV + D1 的组合确实很适合这种轻量级 API 服务场景,开发体验不错。

Comments