实时服务参考

自托管实时服务

Supabase Realtime 是一个基于 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、直接在数据库中、通过控制台等)更改数据库,仍然可以通过 WebSocket 接收变更。
  2. 解耦。例如,如果您想在每次有人购买时发送新的 Slack 消息,您可能会将该功能直接构建到 API 中。这使您可以将异步功能与 API 解耦。
  3. 这是用 Phoenix 构建的,一个极其可扩展的 Elixir 框架

该服务器能保证每个数据变更都能送达吗?

目前还不能!由于以下限制:

  1. PostgreSQL 数据库可能因预写日志(WAL)堆积而耗尽磁盘空间,导致数据库崩溃并阻止 Realtime 服务器接收和广播变更。可以通过在 Realtime RLS 版本中设置 Postgres 配置 max_slot_wal_keep_size 为合理大小来缓解。
  2. Realtime 服务器可能因复制延迟超过可用内存而崩溃,迫使创建新的复制槽并将复制重置为从最新的 WAL 数据读取。
  3. 当 Realtime 服务器因任何原因落后太多时(例如与数据库断开连接时 WAL 继续堆积),数据库可能会删除服务器仍需读取的 WAL 段(例如在重新连接后)。