跳转到内容

Synapse — Matrix 协议的参考 homeserver,让聊天像电邮一样能跨服务器互通

是什么

Synapse 是 Matrix 协议的参考 homeserver——一台你自己架的”聊天邮局服务器”。日常类比:你用 Gmail 给一个 QQ 邮箱发信能到,是因为两家邮局之间走 SMTP 协议。Synapse 就是 Matrix 网络里的”一家邮局”,用户在它上面注册账号、发消息、加房间,再通过联邦协议(federation)跟别家的 homeserver 同步。

它由 Element 公司维护,Python + Twisted 异步框架写成,后期把热路径(状态算法、签名校验)迁到 Rust。

最小启动:

Terminal window
docker run -d --name synapse \
-v ~/synapse-data:/data \
-p 8008:8008 -p 8448:8448 \
matrixdotorg/synapse:latest

跑起来后,你的服务器就能和 matrix.org 这种官方实例互通——别家的人加你房间,消息会经联邦同步过来。

为什么重要

  • 不理解 Synapse,就解释不清”为什么 Slack/Discord 是中心化的、Matrix 不是”——前者数据全在一家公司,后者每个 homeserver 各自存
  • 它是 Matrix 的”参考实现”——协议规范有歧义时,看 Synapse 怎么做就是答案
  • 政府、医院、军方自托管即时通讯几乎都跑 Synapse(德国国家医疗 TI-M 是大宗用户)
  • 想理解 P2P 即时通讯里的”状态最终一致性”,Synapse 的 state resolution v2 是教科书级别的工程参考

核心要点

Synapse 的工程价值集中在 三件事

  1. 房间状态是一棵 DAG:每条消息(PDU)都指向”我看到的最新事件”,多人同时发消息就形成有向无环图。用日常话讲:像群聊里两个人同时回复你,消息没有严格先后,DAG 把这种并发显式画出来。

  2. 联邦冲突用 state resolution v2 解决:两台服务器对”房间 admin 是谁”看法不一致时,跑一个确定性算法投票算出唯一答案——哪台服务器跑都得出同样结果,这是一致性的关键。

  3. Worker 拆分实现水平扩展:单进程 Python 跑不动 matrix.org 这种百万用户实例,所以拆成 federation_sender(专发联邦流量)、synchrotron(专处理客户端长轮询)、event_persister(专写库)等。每个 worker 独立进程,PostgreSQL 共享。

实践案例

案例 1:自架家庭/小公司服务器

最简部署:一台 2C4G VPS + Docker Compose + Caddy 反向代理,20 人以下零运维:

# docker-compose.yml 片段
services:
synapse:
image: matrixdotorg/synapse:latest
volumes: ["./data:/data"]
environment:
SYNAPSE_SERVER_NAME: chat.example.com
SYNAPSE_REPORT_STATS: "no"
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: synapse

docker compose up -d,再用 Element Web 客户端连上去就能聊。

案例 2:大房间联邦的性能挑战

新用户第一次加 matrix.org 上的 1 万人房间(如 #matrix:matrix.org),Synapse 要拉完整状态历史并跑 state resolution。初次加入可能要几分钟到几十分钟,CPU 一直跑满——这是已知性能洞,社区从 2019 年优化到现在还在改。

调试时常用:

Terminal window
# 看 federation 队列是否堆积
curl http://localhost:8008/_synapse/admin/v1/federation/destinations

案例 3:桥接其他平台

Matrix 的杀手锏是 bridge——通过中间程序把 IRC/XMPP/Slack/Discord/WhatsApp 都接进来,统一用 Element 客户端聊天。架构上桥就是一个伪装成 Matrix 用户的机器人 + 真平台账号双向转发。

[Discord 服务器] ←→ mautrix-discord ←→ [Synapse] ←→ Element 客户端

公司里常见用法:把 Slack 历史导入 Matrix 自托管做归档。

踩过的坑

  1. 单进程内存膨胀:默认配置下,联邦流量大的服务器把单 Python 进程吃到 4-8GB。必须拆 worker 才能扛——这是新手最常翻车的点。

  2. 联邦加入大房间慢:上面案例 2 说的几十分钟问题。生产环境给用户的预期管理一定要写清楚,别让他加完房间以为服务器挂了。

  3. PostgreSQL 必须调优:默认配置在中等负载下 IO 会拉满。shared_buffers 至少调到内存 25%,work_mem 调到 16MB,过期事件定期 VACUUM 不然索引膨胀几十 GB。

  4. 升级路径有破坏性:某些版本之间数据库 schema 迁移要离线跑几小时。生产升级前必读 upgrade.md——直接 docker pull latest 是最经典的事故源。

适用 vs 不适用场景

适用

  • 自托管即时通讯 + 跨组织互通的需求(政府、医院、跨公司协作)
  • 强调端到端加密 + 数据主权的合规场景(GDPR、医疗、军工)
  • 桥接多平台聊天到一个客户端
  • 中小规模(10-1000 用户)的 Matrix 部署

不适用

  • 千人以下、不需要联邦的内部 IM → 用 Rocket.Chat / Mattermost 更轻
  • 极端性能场景(10 万 + 用户单服务器)→ 考虑 Dendrite(Go 实现)或 Conduit(Rust 实现)
  • 不需要 E2EE 的客服系统 → 用 chatwoot 这种专门工具
  • 完全无运维能力的团队 → Slack/Discord 仍然更省心

历史小故事(可跳过)

  • 2014 年:Matrix.org 基金会发布协议草案,目标是做”开放标准的 Slack”
  • 2016 年:Synapse 第一版发布(当时叫 synapse-python),Twisted 框架是 Python 异步当年的主流选项
  • 2017 年:Riot.im 客户端(后改名 Element)成为旗舰,Synapse 跟着进入生产可用阶段
  • 2023 年:Element 把仓库从 matrix-org/synapse 迁到 element-hq/synapse,license 改为 AGPLv3,引发社区分叉讨论(Conduit、Dendrite 借机抢用户)
  • 2024 年起:状态算法、签名校验等热路径用 Rust 经 pyo3 重写,性能提升 2-5 倍

学到什么

  1. 去中心化通讯的核心是”状态怎么同步”——DAG + 确定性 resolution 算法,比”谁发得早”靠谱得多
  2. Python + Twisted 单进程不够 → Worker 拆分 + PostgreSQL 共享是 Synapse 教给所有 Python 后端的”水平扩展第一课”
  3. 协议参考实现是双刃剑——大家都照它写,但它的工程包袱(性能、内存)也变成了协议的隐性成本
  4. license 变更会重塑社区——AGPLv3 切换让一部分用户转 Dendrite,开放标准在商业化压力下永远是博弈
  5. Rust 渐进迁移:不要为了”全用一种语言”重写所有,把热点用 pyo3 接进来比从零写一遍 Rust 后端更划算

延伸阅读

关联

  • postgresql —— Synapse 默认且推荐的存储后端,schema 设计深度依赖 PG 特性
  • centrifugo —— 同样做实时消息推送,但走”中心化 pub/sub”路线,对照能看清联邦取舍
  • chatwoot —— 客服向 IM,闭环团队内部,与 Matrix”开放联邦”形成两端
  • redis —— Synapse worker 模式下用 Redis 做 worker 间消息总线
  • nginx —— 生产部署的反向代理首选,处理 TLS + WebSocket 升级
  • haproxy —— 大流量场景替代 Nginx 做 Matrix 端口的 L4/L7 负载
  • celery —— Python 后台任务的对照思路,Synapse 选了 worker + Redis 而非 Celery

反向链接

  • celery —— Celery — Python 把慢任务搬到后台干的工头
  • centrifugo —— Centrifugo — Go 写的开源实时消息服务器
  • chatwoot —— chatwoot — 把 11 种外部聊天渠道归一到同一张消息表
  • conduit —— Conduit — Rust 写的极简 Matrix homeserver,单二进制 + 嵌入式数据库
  • dendrite —— Dendrite — Go 写的第二代 Matrix homeserver,组件可拆可合
  • element-android —— Element Android — Matrix 协议官方 Android 客户端(Kotlin + Realm)
  • element-web —— Element Web — Matrix 协议旗舰 web 客户端(React + matrix-js-sdk)
  • haproxy —— HAProxy — 高性能 LB,TCP/HTTP 双层负载均衡
  • matrix-js-sdk —— matrix-js-sdk — Matrix Web/Node 端的”老大哥”客户端 SDK
  • matrix-rust-sdk —— matrix-rust-sdk — Matrix 客户端的”共享发动机”
  • nginx —— nginx — 高性能 Web 服务器
  • postgresql —— PostgreSQL — 工业级关系数据库
  • redis —— Redis — 内存键值数据库
  • rocket-chat —— Rocket.Chat — 开源 Slack 替代,Meteor + MongoDB 全栈实时聊天