自托管实时功能
Supabase 实时服务器是一个使用 Elixir 构建的服务器,它使用 Phoenix Framework 监听 PostgreSQL 数据库中的更改,通过逻辑复制,然后通过 WebSocket 广播这些更改。
此服务器有两个版本:Realtime 和 Realtime RLS。
Realtime 服务器的工作方式是
- 监听 PostgreSQL 的复制功能(使用 PostgreSQL 的逻辑解码)
- 将字节流转换为 JSON
- 通过 WebSocket 向所有连接的客户端广播
Realtime RLS 服务器的工作方式是
- 轮询 PostgreSQL 的复制功能(使用 PostgreSQL 的逻辑解码和 wal2json 输出插件)
- 将数据库更改传递给 Write Ahead Log Realtime Unified Security (WALRUS) PostgreSQL 函数,并根据行级别安全 (RLS) 策略接收授权订阅者列表
- 将更改转换为 JSON
- 通过 WebSocket 向授权订阅者广播
为什么不直接使用 PostgreSQL 的 NOTIFY?#
几个原因
- 您不必在每个表上设置触发器。
NOTIFY的有效载荷限制为 8000 字节,对于更大的内容将会失败。通常的解决方案是发送一个 ID 然后获取记录,但这会给数据库带来很大的负担。Realtime服务器消耗两个数据库连接,然后您可以将许多客户端连接到此服务器。减轻数据库负担,并且要扩展,只需添加额外的Realtime服务器即可。
优势#
- 监听复制功能的优点在于,您可以从任何地方更改数据库 - 您的 API、直接在 DB 中、通过控制台等 - 您仍然会通过 WebSocket 接收更改。
- 解耦。例如,如果您想在每次有人进行新购买时发送一条新的 Slack 消息,您可能会将此功能直接构建到您的 API 中。这允许您将异步功能从 API 中解耦。
- 这是使用 Phoenix 构建的,一个 极其可扩展的 Elixir 框架。
此服务器是否保证传递每个数据更改?#
尚未!由于以下限制
- Postgres 数据库由于 Write-Ahead Logging (WAL) 的累积而耗尽磁盘空间,这可能会导致数据库崩溃并阻止实时服务器接收和广播更改。可以通过此服务器的 Realtime RLS 版本将 Postgres 配置
max_slot_wal_keep_size设置为合理大小来缓解此问题。 - 实时服务器可能会因比可用内存更大的复制滞后而崩溃,从而强制创建新的复制槽并重置复制以从最新的 WAL 数据读取。
- 当实时服务器由于任何原因落后太远时,例如在 WAL 继续累积时从数据库断开连接,然后数据库可能会删除服务器仍然需要读取的 WAL 段,例如在重新连接后。