实时服务器参考

自托管实时功能

Supabase 实时服务器是一个使用 Elixir 构建的服务器,它使用 Phoenix Framework 监听 PostgreSQL 数据库中的更改,通过逻辑复制,然后通过 WebSocket 广播这些更改。

此服务器有两个版本:RealtimeRealtime RLS

Realtime 服务器的工作方式是

  1. 监听 PostgreSQL 的复制功能(使用 PostgreSQL 的逻辑解码)
  2. 将字节流转换为 JSON
  3. 通过 WebSocket 向所有连接的客户端广播

Realtime RLS 服务器的工作方式是

  1. 轮询 PostgreSQL 的复制功能(使用 PostgreSQL 的逻辑解码和 wal2json 输出插件)
  2. 将数据库更改传递给 Write Ahead Log Realtime Unified Security (WALRUS) PostgreSQL 函数,并根据行级别安全 (RLS) 策略接收授权订阅者列表
  3. 将更改转换为 JSON
  4. 通过 WebSocket 向授权订阅者广播

为什么不直接使用 PostgreSQL 的 NOTIFY#

几个原因

  1. 您不必在每个表上设置触发器。
  2. NOTIFY 的有效载荷限制为 8000 字节,对于更大的内容将会失败。通常的解决方案是发送一个 ID 然后获取记录,但这会给数据库带来很大的负担。
  3. Realtime 服务器消耗两个数据库连接,然后您可以将许多客户端连接到此服务器。减轻数据库负担,并且要扩展,只需添加额外的 Realtime 服务器即可。

优势#

  1. 监听复制功能的优点在于,您可以从任何地方更改数据库 - 您的 API、直接在 DB 中、通过控制台等 - 您仍然会通过 WebSocket 接收更改。
  2. 解耦。例如,如果您想在每次有人进行新购买时发送一条新的 Slack 消息,您可能会将此功能直接构建到您的 API 中。这允许您将异步功能从 API 中解耦。
  3. 这是使用 Phoenix 构建的,一个 极其可扩展的 Elixir 框架

此服务器是否保证传递每个数据更改?#

尚未!由于以下限制

  1. Postgres 数据库由于 Write-Ahead Logging (WAL) 的累积而耗尽磁盘空间,这可能会导致数据库崩溃并阻止实时服务器接收和广播更改。可以通过此服务器的 Realtime RLS 版本将 Postgres 配置 max_slot_wal_keep_size 设置为合理大小来缓解此问题。
  2. 实时服务器可能会因比可用内存更大的复制滞后而崩溃,从而强制创建新的复制槽并重置复制以从最新的 WAL 数据读取。
  3. 当实时服务器由于任何原因落后太远时,例如在 WAL 继续累积时从数据库断开连接,然后数据库可能会删除服务器仍然需要读取的 WAL 段,例如在重新连接后。