杂谈:去中心化社区是如何实现的

深入解析:去中心化社区、联邦模式与 ActivityPub

1. 核心概念:中心化 vs. 联邦式

要理解“去中心化”,我们先看看它的反面。

  • 中心化 (Centralized)

    • 例子:Twitter, Facebook, Reddit, 抖音。
    • 如何工作:所有用户数据、帖子、关系链都储存在 一个 公司控制的服务器(集群)上。
    • 优点:体验统一,易于管理,功能迭代快。
    • 缺点:单点故障(服务宕机=全玩完),数据被单一实体控制(隐私、审核、算法黑箱),审查风险。
  • 联邦式 (Federated)

    • 例子Mastodon (微博客), Matrix (即时通讯), Lemmy (论坛), PeerTube (视频)。
    • 如何工作:想象一下 电子邮件 (Email)
      • 你可以在 gmail.com 注册,我可以在 outlook.com 注册。
      • gmail.comoutlook.com完全独立 的服务器,由不同公司运营。
      • 但是,因为它们都使用相同的协议 (SMTP),你的 Gmail 账户可以给我的 Outlook 账户发邮件,反之亦然。
    • 联邦式社区就是这样:
      1. 世界上有成百上千个独立的服务器(称为 “实例” / Instance)。
      2. 你可以在任何一个实例上注册账户 (例如 @[email protected])。
      3. 这些独立的实例使用 共同的协议(比如 ActivityPub)来互相“交谈”、交换帖子和通知。
      4. 你在 social.server.com 上的帖子,可以被 another.server.net 上的朋友看到、点赞和转发。

简而言之:联邦制 = 许多独立运行的服务器,它们同意使用同一种“语言”(协议)来互联互通,形成一个更大的网络。没有“中心”服务器

2. 关键玩家:Mastodon vs. Matrix

它们解决的问题不同,使用的协议也不同。

  • Mastodon (长毛象)

    • 做什么:微博客(类似 Twitter)。
    • 协议ActivityPub
    • 工作方式:你的账户在 A 实例上,你可以“关注” B 实例上的另一个用户。当你发帖时,你的 A 实例会把这条帖子推送给 B 实例(以及其他所有有你粉丝的实例)。
  • Matrix (矩阵)

    • 做什么:即时通讯(类似 Slack, Discord, WhatsApp)。
    • 协议Matrix 协议(一个独立的开放标准)。
    • 工作方式:它更侧重于 房间 (Rooms) 的同步。Matrix 的核心是“去中心化的实时对话数据同步”。你的账户 (@user:homeserver.org) 可以加入一个房间,这个房间的状态被同步到所有参与者所在的“家庭服务器”(Homeserver)上。

3. 深入解析:联邦 (Federation) 和 ActivityPub

这是问题的核心。

什么是联邦模式 (Federation)?

如前所述,它是“实例”的互联网络。

  • 实例 (Instance):一个独立的服务器,运行着 Mastodon、Lemmy 或你开发的软件。它有自己的用户数据库、帖子、管理规则。
  • 联邦 (Federation):当实例 A 上的用户 User_A 想要关注实例 B 上的 User_B 时,AB 两个服务器就开始了“联邦”关系。它们会交换公钥,开始互相推送和接收内容。
  • 你的“时间线”:你的主页时间线(Home Timeline)是你关注的所有人(无论他们在哪个实例上)的帖子集合。
  • “本地”与“联邦”时间线 (Local vs. Federated)
    • 本地 (Local):只显示你 当前所在实例 上所有公开帖子的时间线。
    • 联邦 (Federated):显示你的实例“知道”的所有公开帖子(即你实例上的用户所关注的所有外部实例的帖子)。

什么是 ActivityPub 协议?

如果联邦模式是“规则”,ActivityPub 就是“语言”。它是一个 W3C 官方标准

ActivityPub 的核心非常简单。它把所有社交互动都抽象为 “活动” (Activities)

一个“活动” = 行动者 (Actor) + 动作 (Activity) + 对象 (Object)

  • Actor (行动者):发起动作的人。
  • Object (对象):被操作的东西。
    • 可以是一篇“笔记”(Note,即你的帖子内容)。
    • 可以是一个“图片”(Image)。
    • 可以是另一个 Actor(比如你“关注”的对象)。
  • Activity (活动):你所做的“动作”(动词)。
    • Create (创建):你(Actor)创建 (Activity) 了一篇帖子 (Object)。
    • Follow (关注):你(Actor)关注 (Activity) 了另一个用户 (Object)。
    • Like (点赞):你(Actor)点赞 (Activity) 了一篇帖子 (Object)。
    • Announce (转发/Boost):你(Actor)转发 (Activity) 了一篇帖子 (Object)。

这一切如何运作? (技术流程)

  1. 收件箱 (Inbox) 和 发件箱 (Outbox)

    • 每个 Actor (用户) 都有一个 inbox 和一个 outbox。它们是 API 端点 (Endpoints)。
    • Outbox (发件箱):当你做某事时(比如发帖),你的服务器会把这个“活动”(一个 JSON 数据包)放入你的 outbox
    • Inbox (收件箱):其他服务器用来给你(或你的实例)发送“活动”的地方。
  2. 一个发帖的例子

    1. 你(@user_A@server_A.com)在你的论坛上点击“发布”。
    2. 你的 客户端(网页或 App)向你的 服务器 server_A 发送请求。
    3. server_A 创建一个 Create 活动(一个包含你帖子内容的 JSON 对象)。
    4. server_A 查看你的 关注者列表。它发现你有3个关注者:
      • @user_B@server_A.com (本地用户)
      • @user_C@server_B.com
      • @user_D@server_C.com
    5. server_A 执行 这个活动:
      • 对于 user_B(本地),它直接把帖子写入 user_B 的时间线数据库。
      • 对于 user_Cuser_D(联邦),server_A 会向 server_Bserver_Cinbox API 端点 POST 这个 Create 活动的 JSON 数据。
    6. server_B 收到这个 JSON,验证它(使用 HTTP 签名确保它真的来自 server_A),然后处理它,把它插入到 user_C 的时间线数据库中。server_C 同理。
    7. 大功告成!一个帖子在3个不同的服务器之间同步了。

4. 如何开发一个“联邦式论坛”?

好了,进入正题。如果你想自己做一个(比如一个 ActivityPub 版的 Reddit 或 Discuz),你需要做什么。

这是一个非常、非常复杂的工作。你不仅要构建一个功能齐全的论坛(这本身就很难),还要实现一个复杂、安全、健壮的联邦协议。

阶段 1:构建一个“单机版”论坛

在考虑“联邦”之前,你必须先有一个能用的、普通的、中心化的论坛。

  1. 技术栈
    • 后端:Python (Django/FastAPI), Go, Rust, Node.js (Express)… 选你最熟的。
    • 数据库:PostgreSQL 是首选(处理 JSONB 数据很方便)。
    • 前端:React, Vue, Svelte, 或者传统服务端渲染。
  2. 核心功能
    • 用户注册和登录(本地账户)。
    • 创建“社区”或“版块” (Subreddits)。
    • 发布帖子(标题、内容)。
    • 发表评论。
    • 投票(点赞/踩)。

阶段 2:拥抱 ActivityPub (联邦化)

这是最难的部分。你需要把你的“本地论坛”变成一个“联邦公民”。

1. 身份表示 (Identity)

  • WebFinger:你需要实现这个协议。
    • server_B 想知道 @user_A@server_A.com 是谁时,它会查询 server_A.com/.well-known/webfinger?resource=acct:user_A@server_A.com
    • 你的服务器必须返回一个 JSON,告诉 server_B 这个用户的 Actor ID (通常是一个 URL,比如 https://server_A.com/users/user_A)。

2. 实现 Actor (行动者)

  • 你的论坛需要定义至少两种 Actor
    • Person:代表你的用户。
    • GroupService:代表你的“社区/版块”。这允许其他联邦宇宙的用户(比如 Mastodon 用户)“关注”你的一个版块。
  • 每个 Actor 都必须有一个 唯一的 ID (URL),访问这个 URL 应该返回描述这个 Actor 的 JSON-LD (ActivityPub 使用的 JSON 格式)。

3. 实现 Inbox 和 Outbox

  • inbox (API 端点):这是你的服务器的“公共入口”。
    • 共享收件箱 (Shared Inbox):通常为整个实例设置一个共享 inbox (e.g., /inbox) 来接收所有联邦活动,以提高效率。
    • 处理活动:这是你后端的核心逻辑。当 server_B 向你的 inbox POST 一个 Like 活动时,你的代码需要:
      1. 验证 HTTP 签名极其重要! 否则任何人都可以伪造活动)。
      2. 解析这个 Like 活动。
      3. 在你的数据库里找到被点赞的帖子。
      4. 给这个帖子的点赞数+1。
  • outbox (API 端点)
    • 当你的本地用户 user_A 创建了一个帖子,你的服务器会生成一个 Create 活动。
    • 你的服务器需要有一个 队列系统 (Sidekiq, Celery, RabbitMQ) 来处理“联邦投递”。
    • 这个系统会查询 user_A 的关注者列表,找到所有外部服务器(server_B, server_C…),然后把这个 Create 活动 POST 到它们各自的 inbox

4. 实现特定的“论坛”活动

  • 关注 (Follow):你需要处理来自外部用户的 Follow 活动(关注你的用户或你的版块)。
  • 创建帖子 (Create Note/Article):当你的用户发帖时,你需要把它打包成 Create 活动发送出去。
  • 创建评论 (Create Note … inReplyTo):评论只是一个 Note (帖子),它有一个 inReplyTo 字段指向它所回复的帖子。
  • 点赞 (Like) / 转发 (Announce):处理流入和流出的这些活动。

阶段 3:联邦的黑暗面(你需要处理的烂摊子)

  • 审核 (Moderation):这是联邦宇宙的头号难题。
    • 如果 spam_server.com 开始向你的实例发送大量垃圾邮件怎么办?
    • 你需要实现“实例黑名单” (Defederation),允许你(作为管理员)屏蔽整个 spam_server.com
  • 存储 (Storage)
    • server_B 的用户向你的论坛发帖时,如果帖子带了图片或视频…恭喜你,你的服务器现在需要**缓存(并永久存储)**这些媒体文件。
    • 你的存储成本会因为“联邦”而急剧上升。
  • 发现 (Discovery)
    • 你的实例刚上线时,是座孤岛。你需要一些机制(比如 Relays)来帮助你的实例发现其他实例并交换内容。

总结

构建一个去中心化的联邦式社区是一项崇高但极其复杂的工作。

  • 它依赖于“联邦模式”,即 独立的服务器
  • 它通过“共同语言” ActivityPub 来实现互操作。
  • ActivityPub 将所有社交行为(发帖、点赞、关注)都视为 Activities (活动),并通过 inboxoutbox 在服务器之间传递。