Supabase Realtime分布式部署:多节点集群配置
你是否正在为实时应用的高可用性和扩展性发愁?单节点部署面临性能瓶颈和单点故障风险,而多节点集群部署能显著提升系统稳定性与并发处理能力。本文将带你一步步完成Supabase Realtime的分布式部署,从环境准备到集群验证,全程实操无废话,读完即可上手配置生产级分布式系统。
核心架构概览
Supabase Realtime基于Elixir/Erlang构建,天生支持分布式特性。其集群架构主要通过以下组件实现节点协同:
- 节点发现机制:通过DNS或PostgreSQL实现节点自动发现与连接
- 分布式Pub/Sub:基于gen_rpc实现跨节点消息传递
- 数据库复制:利用PostgreSQL的复制功能确保数据一致性
- 负载均衡:自动分发客户端连接与订阅请求
核心配置文件包括:
- 集群策略配置:config/runtime.exs
- Docker编排配置:docker-compose.yml
- 生产环境部署:deploy/fly/prod.toml
环境准备与依赖
硬件要求
分布式部署建议每个节点至少满足:
- CPU:2核以上
- 内存:4GB RAM
- 存储:20GB SSD
- 网络:1Gbps以上,节点间低延迟连接
软件依赖
确保所有节点已安装:
- Docker Engine 20.10+
- Docker Compose 2.0+
- Git
- 网络时间同步服务(ntpd/chronyd)
源码获取
首先克隆项目源码到所有节点:
git clone https://gitcode.com/gh_mirrors/re/realtime
cd realtime
项目主要依赖在mix.exs中定义,核心分布式组件包括:
- libcluster: 集群节点管理
- libcluster_postgres: 基于PostgreSQL的节点发现
- gen_rpc: 跨节点RPC通信
- syn: 分布式进程注册
集群配置详解
1. 数据库配置
分布式部署需要共享PostgreSQL数据库,推荐使用主从架构。修改docker-compose.yml配置数据库:
services:
db:
image: supabase/postgres:14.1.0.105
container_name: realtime-db
ports:
- "5432:5432"
volumes:
- ./dev/postgres:/docker-entrypoint-initdb.d/
command: postgres -c config_file=/etc/postgresql/postgresql.conf
environment:
POSTGRES_HOST: /var/run/postgresql
POSTGRES_PASSWORD: postgres
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
2. 节点发现配置
Supabase Realtime支持多种集群发现策略,配置文件位于config/runtime.exs。生产环境推荐使用PostgreSQL策略:
# 在config/runtime.exs中配置
config :libcluster,
topologies: [
postgres: [
strategy: LibclusterPostgres.Strategy,
config: [
hostname: System.get_env("DB_HOST"),
username: System.get_env("DB_USER"),
password: System.get_env("DB_PASSWORD"),
database: System.get_env("DB_NAME"),
port: System.get_env("DB_PORT"),
heartbeat_interval: 5_000
]
]
]
也可使用DNS策略(适用于Kubernetes等环境):
# DNS节点发现配置示例
dns: [
strategy: Cluster.Strategy.DNSPoll,
config: [
polling_interval: 5_000,
query: System.get_env("DNS_NODES"),
node_basename: app_name
]
]
3. 分布式通信配置
跨节点通信通过gen_rpc实现,配置TCP或SSL通信方式。在生产环境建议使用SSL加密:
# 在config/runtime.exs中配置gen_rpc
config :gen_rpc,
ssl_server_port: 6369,
ssl_client_port: 6369,
ssl_client_options: [
certfile: System.fetch_env!("GEN_RPC_CERTFILE"),
keyfile: System.fetch_env!("GEN_RPC_KEYFILE"),
cacertfile: System.fetch_env!("GEN_RPC_CACERTFILE")
],
ssl_server_options: [
certfile: System.fetch_env!("GEN_RPC_CERTFILE"),
keyfile: System.fetch_env!("GEN_RPC_KEYFILE"),
cacertfile: System.fetch_env!("GEN_RPC_CACERTFILE")
]
4. 资源限制与性能调优
为避免单节点过载影响整个集群,需配置资源限制。在config/runtime.exs中设置租户级别的资源限制:
# 租户资源限制配置
config :realtime,
tenant_max_concurrent_users: 200,
tenant_max_events_per_second: 100,
tenant_max_channels_per_client: 100,
tenant_max_joins_per_second: 100
根据服务器性能调整连接数和进程限制:
# WebSocket连接配置
config :realtime, RealtimeWeb.Endpoint,
http: [
transport_options: [
max_connections: 1000,
num_acceptors: 100
]
]
部署步骤
使用Docker Compose部署
- 准备环境变量文件
在每个节点创建.env文件:
# 数据库配置
DB_HOST=主数据库IP
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=安全密码
DB_NAME=postgres
DB_ENC_KEY=生成的加密密钥
# 节点配置
APP_NAME=realtime-cluster
SECRET_KEY_BASE=生成的安全密钥
API_JWT_SECRET=生成的JWT密钥
DNS_NODES=realtime-cluster.internal
ERL_AFLAGS=-proto_dist inet_tcp
- 启动集群
在所有节点执行启动命令:
docker-compose up -d
- 初始化数据库
在主节点执行数据库迁移:
docker-compose exec realtime bin/migrate
使用Fly.io部署(生产环境)
对于生产环境,推荐使用Fly.io进行部署,配置文件位于deploy/fly/prod.toml:
- 安装Fly CLI
curl -L https://fly.io/install.sh | sh
- 初始化应用
fly launch --config deploy/fly/prod.toml
- 部署多区域集群
# 创建多个区域的应用实例
fly regions add ord # 芝加哥
fly regions add sfo # 旧金山
fly regions add lhr # 伦敦
# 扩展到每个区域2个节点
fly scale count 2 --region ord
fly scale count 2 --region sfo
fly scale count 2 --region lhr
配置自动扩缩容:
# 在deploy/fly/prod.toml中添加
[autoscaling]
min_machines_running = 2
max_machines_running = 10
[[services.autoscaling]]
policy = "cpu"
target_percentage = 70
集群验证与监控
节点状态检查
检查集群节点是否正常连接:
# 查看集群节点
docker-compose exec realtime bin/realtime remote
> :observer.start()
在Observer窗口的"Nodes"标签中可以看到所有已连接的节点。
分布式功能测试
- 创建测试订阅
// 客户端测试代码
const { RealtimeClient } = require('@supabase/realtime-js')
const client = new RealtimeClient('ws://负载均衡器IP:4000/socket', {
params: { apikey: 'anon_key' }
})
const channel = client.channel('test-channel')
channel.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'test' }, (payload) => {
console.log('Change received:', payload)
})
channel.subscribe()
- 在数据库插入测试数据
INSERT INTO public.test (data) VALUES ('cluster-test');
- 验证所有节点都能接收到变更事件
监控指标
Supabase Realtime内置Prometheus指标,配置lib/realtime/monitoring/prom_ex.ex后,可通过/metrics端点获取监控数据:
curl http://节点IP:4000/metrics
关键监控指标包括:
realtime_tenant_connections:每个租户的连接数realtime_channel_count:活跃频道数realtime_rpc_requests_total:跨节点RPC请求数realtime_postgres_replication_lag:数据库复制延迟
常见问题与解决方案
节点无法加入集群
症状:节点启动后未出现在集群列表中
排查步骤:
- 检查网络连通性:确保所有节点间6369端口( gen_rpc )可通信
- 验证数据库连接:确认lib/realtime/repo.ex配置正确
- 查看日志:
docker-compose logs realtime | grep cluster
解决方案:
# 重启节点发现服务
docker-compose exec realtime bin/realtime rpc Realtime.Nodes.reload
数据同步延迟
症状:节点间数据同步存在明显延迟
排查步骤:
- 检查PostgreSQL复制状态:
SELECT * FROM pg_stat_replication; - 监控网络延迟:节点间ping值应低于10ms
- 检查系统资源:CPU/内存使用率是否过高
解决方案:
- 优化数据库配置,增加WAL发送缓冲区
- 减少单节点负载,增加节点数量
- 调整config/runtime.exs中的复制参数
客户端连接不均衡
症状:部分节点连接数远高于其他节点
解决方案:
- 确保负载均衡器配置正确,启用会话亲和性
- 调整客户端重连逻辑,添加随机延迟
- 配置区域感知路由:
# 在config/runtime.exs中启用区域广播
config :realtime,
regional_broadcasting: true,
region: "us-east" # 每个节点设置为所在区域
最佳实践与扩展建议
高可用配置
- 多区域部署:至少在3个地理区域部署节点
- 自动故障转移:结合外部监控实现节点自动替换
- 数据备份:配置PostgreSQL定时备份,启用时间点恢复(PITR)
安全加固
- 网络隔离:只暴露必要端口,使用私有网络通信
- TLS加密:为所有节点间通信启用SSL/TLS
- 权限控制:遵循最小权限原则配置服务账户
- 密钥轮换:定期更新config/runtime.exs中的密钥
未来扩展路径
随着业务增长,可考虑以下扩展方向:
- 读写分离:配置只读副本分担查询压力
- 垂直分片:按租户ID范围拆分集群
- 功能解耦:将extensions中的功能独立部署
- 边缘计算:利用Fly.io或CDN将服务部署到边缘位置
总结
通过本文的步骤,你已成功部署Supabase Realtime分布式集群,实现了系统的高可用与弹性扩展。关键要点包括:
- 利用Elixir/Erlang的分布式特性构建集群
- 选择合适的节点发现策略(DNS或PostgreSQL)
- 配置合理的资源限制与性能参数
- 实施完善的监控与故障转移机制
Supabase Realtime的分布式架构为实时应用提供了坚实基础,无论是物联网数据流、协作工具还是实时分析平台,都能从中受益。如需进一步优化,可深入研究lib/realtime/tenants.ex中的租户隔离机制,或lib/realtime/channels/目录下的通道管理代码。
现在,你的实时应用已经具备企业级的稳定性和扩展性,准备好迎接海量并发连接和实时数据处理挑战了!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



