Hotdry.
systems

Peerweb 如何利用 WebTorrent 实现去中心化网站托管

分析 Peerweb 利用 WebTorrent 实现去中心化网站托管的技术细节,包括数据分片策略、DHT 网络发现机制与缓存淘汰策略。

在传统网站托管架构中,中心化服务器承载着单点故障的风险。一旦服务器遭受攻击或被强制下线,网站便从互联网上消失。Peerweb 提出了一种激进但工程上可行的替代方案:利用 WebTorrent 协议将静态网站转化为 P2P 分布的 torrent 种子,用户通过浏览器直接与其他访问者交换数据,彻底摆脱对中心化基础设施的依赖。这一架构的核心挑战在于如何高效地将网站内容分片、如何在去中心化网络中可靠地发现节点、以及如何在浏览器有限的存储空间中管理缓存生命周期。

数据分片策略:16KB 块与 80KB 片的工程选择

WebTorrent 继承自 BitTorrent 协议的分片机制,但在浏览器环境下进行了适度调整。标准实现中,数据被切分为固定大小的块(chunk),每 5 个块组成一个片(piece)。根据 torrent-piece 库的代码定义,BLOCK_LENGTH 常量被设定为 16384 字节,即 16KB。这意味着每个 piece 的大小约为 80KB(5 × 16384),这一数值在下载效率与内存占用之间取得了平衡。

对于网站托管场景,分片策略的工程意义体现在多个层面。首先,16KB 的块粒度允许浏览器在网络波动时快速恢复传输,无需重新下载整个文件。其次,80KB 的片大小使得校验操作可以按片进行,当某片数据损坏时仅需重传该片而非整个网站资源。Peerweb 在处理网站上传时,会递归扫描目录结构,收集所有文件元数据后生成统一的 torrent 元数据文件。该元数据包含文件分片映射表,访问者在加载网站时首先获取元数据,再根据分片哈希值向网络请求具体内容。

值得注意的是,浏览器环境的 WebRTC 数据传输限制对分片策略产生了额外约束。在 WebRTC 直连场景中,每次发送的字节数通常不超过 16KB,这与 torrent 协议的块大小设计不谋而合。这种一致性简化了端到端的数据校验流程,避免了在应用层引入额外的分片逻辑。Peerweb 通过本地索引(IndexedDB)缓存已下载的分片,当用户再次访问同一网站时,优先从本地存储读取数据,仅向网络请求缺失的分片,从而显著降低首屏加载时间。

DHT 网络发现:从种子哈希到可用节点的寻址过程

分布式哈希表(DHT)是 WebTorrent 实现去中心化的关键组件。与传统 BitTorrent 依赖集中式_tracker 服务器不同,WebTorrent 客户端通过 DHT 协议在网络中自主发现拥有目标内容的 peers。Peerweb 的访问流程始于用户打开一个形如 https://peerweb.lol/?orc=<hash> 的链接,其中 <hash> 是网站对应的 torrent infohash。

当浏览器加载该 URL 时,WebTorrent 客户端首先初始化本地 DHT 节点。每个节点在加入网络时需要 bootstrap 节点列表,标准配置通常包含 router.bittorrent.com、router.utorrent.com 等公共节点。节点间通过 Kademlia 变体协议交换路由信息,逐步构建覆盖全网络的分布式路由表。新节点通过与 bootstrap 节点通信,获取距离自身节点 ID 最近的已知节点,并递归查询直到定位到目标 infohash 对应的 peers。

在浏览器环境中实现 DHT 面临独特的挑战。浏览器无法直接监听 UDP 端口,因此 WebTorrent 使用 WebRTC 作为传输层,通过信令服务器建立 peers 间的直接连接。这意味着 DHT 消息实际上是通过 WebRTC DataChannel 发送的,节点发现过程与传统的 UDP DHT 有所不同。Peerweb 的工程实现需要在应用层维护一个轻量级的 DHT 客户端,它能够在后台静默运行,不断向网络查询目标 infohash 的可用 peers,并向已发现的 peers 发起 WebRTC 连接请求以建立数据通道。

节点发现的质量直接影响网站加载的成功率。如果某一时刻网络中没有任何 peers 在线,访问请求将永久挂起。Peerweb 通过鼓励用户运行桌面客户端来维持种子健康度,同时在 Web 界面上清晰提示用户 "保持此标签页打开以托管网站"。这种设计将一部分存储与带宽成本转移给了内容发布者和热心访问者,形成了自组织的去中心化托管网络。

缓存淘汰机制:IndexedDB 存储与七天过期策略

去中心化网络的高延迟特性使得缓存成为提升用户体验的关键优化点。Peerweb 实现了基于 IndexedDB 的智能缓存系统,其核心策略包含三个维度:存储持久化、访问速度优化和空间自动管理。

当用户首次访问某个网站时,WebTorrent 客户端按需下载分片数据。每完成一个分片的校验,数据即被写入 IndexedDB。由于 IndexedDB 是浏览器原生的持久化存储方案,缓存数据在会话结束后依然保留,用户下次访问同一网站时可以直接从本地读取已缓存的分片,无需重新从网络下载。这一机制对于包含大量静态资源(图片、字体、样式表)的大型网站尤为有效,能够将二次访问的加载时间从秒级降低到毫秒级。

缓存淘汰策略采用了基于时间的 TTL(Time-To-Live)机制。Peerweb 官方文档明确指出,缓存会在 7 天后自动过期清理。这一设计决策背后有多重考量。首先,网站内容可能随时间更新,过期缓存会导致用户看到过期信息。其次,浏览器对 IndexedDB 的存储配额存在隐性限制,不同浏览器和设备的配额各异,强制过期可以防止存储空间被陈旧数据耗尽。第三,7 天是一个经验性周期,既能覆盖大多数用户的重复访问模式,又不会因期限过短而频繁触发重新下载。

在空间管理层面,当 IndexedDB 存储接近配额上限时,Peerweb 会触发清理逻辑,优先删除最久未访问的缓存条目。这一 LRU(Least Recently Used)策略确保了活跃网站的缓存优先保留。清理操作对用户透明执行,通常在后台静默完成,不会阻塞主线程或影响当前页面渲染。

工程实现的权衡与安全考量

将去中心化托管理念落地为可用的浏览器产品,需要解决一系列工程权衡问题。安全性是首要考量:由于 Peerweb 直接在浏览器中执行来自 P2P 网络的 HTML、JavaScript 和 CSS,恶意代码可能窃取用户凭证或执行 XSS 攻击。Peerweb 通过 DOMPurify 对所有传入的 HTML 内容进行净化处理,移除潜在的 script 标签、事件处理器和危险属性。同时,网站内容被渲染在沙箱化的 iframe 中,与主页面隔离,防止跨域数据泄露。

浏览器兼容性是另一层约束。WebRTC DataChannel 和 ServiceWorker 是 Peerweb 运行的基础 API,但这些特性在不同浏览器中的支持程度不一。历史版本的 Chromium(49 之前)存在 ServiceWorker 无法加载 blob 文件的 bug,而 Firefox 的早期 ServiceWorker 实现与 WebSocket 存在冲突。Peerweb 的工程文档建议使用 Chromium 49 及以上版本,或直接使用桌面客户端以规避浏览器兼容性问题。

最后,种子健康度的维护是去中心化架构的固有挑战。与传统 CDN 的全球化节点部署不同,Peerweb 的可用性完全依赖于种子持有者的在线意愿。发布者可以选择运行桌面客户端永久做种,但普通访问者通常仅在访问期间保持在线。Peerweb 通过激励机制鼓励用户贡献带宽 —— 访问者在下载的同时也在向其他用户上传数据,形成互惠的 P2P 传输网络。对于关键内容,发布者可能需要部署多个种子或鼓励社区成员协助做种,以提升抗审查能力和可用性上限。


参考资料

  1. PeerWeb 官方网站:https://peerweb.lol/
  2. GitHub - webtorrent/torrent-piece:https://github.com/webtorrent/torrent-piece
查看归档