如何结合Node.js Cluster与PM2跨多台Digital Ocean Droplets扩展SocketCluster?
SocketCluster + Node.js Cluster 跨Droplet横向扩展故障排查与解决方案
核心问题定位与配置修正
1. SocketCluster集群模式配置检查
SocketCluster的集群依赖worker和broker进程的协作,必须确保以下配置正确:
- 启用
workerController和brokerController文件,这两个文件负责处理进程间消息路由和业务逻辑分发,缺失会直接导致集群通信失效。 - 通过环境变量明确
brokerClusterOptions中的isWorker和isBroker标识,PM2启动时要严格区分两类进程,避免角色混乱。
2. 跨Droplet网络通信验证
多Droplet部署时,网络连通性是核心前提:
- 所有Droplet的防火墙必须开放SocketCluster的服务端口(默认8000)和broker内部通信端口(默认8001),同时允许Droplet私有IP网段的访问权限。
- 配置SocketCluster的
hostname为0.0.0.0(绑定所有网卡),并在brokerOptions中指定Droplet的私有IP作为通信地址,禁止绑定到localhost(否则跨机器无法建立连接)。
3. PM2进程管理配置优化
PM2的ecosystem.config.js需要分别配置broker和worker进程,示例如下:
module.exports = { apps: [ { name: 'sc-broker', script: 'node_modules/socketcluster/scBroker.js', instances: 1, // 单Droplet建议部署1个broker,多Droplet需每台机器都部署 exec_mode: 'fork', // broker用fork模式,避免cluster模式下的端口冲突 env: { SC_BROKER: true, SC_BROKER_HOST: '你的Droplet私有IP', SC_BROKER_PORT: 8001 } }, { name: 'sc-worker', script: 'server.js', // 你的SocketCluster服务入口文件 instances: 'max', // 根据CPU核心数自动启动worker进程 exec_mode: 'cluster', env: { SC_WORKER: true, SC_BROKER_HOST: '你的Droplet私有IP', SC_BROKER_PORT: 8001 } } ] };
4. SocketCluster服务端核心配置示例
调整你的server.js配置,适配多Droplet集群场景:
const SocketCluster = require('socketcluster'); const scServer = new SocketCluster({ port: 8000, hostname: '0.0.0.0', workerController: __dirname + '/worker.js', brokerController: __dirname + '/broker.js', brokerClusterOptions: { isWorker: process.env.SC_WORKER === 'true', isBroker: process.env.SC_BROKER === 'true', discoveryMode: 'static', // 多Droplet用静态broker列表实现跨机器通信 staticPeers: [ 'droplet1-private-ip:8001', 'droplet2-private-ip:8001' // 加入所有Droplet的broker地址 ] }, wsEngine: 'ws', allowClientPublish: false });
故障排查步骤
- 查看PM2日志:执行
pm2 logs sc-worker和pm2 logs sc-broker,重点排查端口占用、broker连接超时、握手失败等错误信息。 - 单Droplet验证:先在单台Droplet上启动完整集群,用客户端测试WebSocket连接和消息收发,确认功能正常后再扩展到多机器。
- 网络连通性测试:用
telnet 目标Droplet私有IP 8001测试broker端口是否能连通,排除防火墙或网络配置问题。
负载均衡补充
多Droplet前端需配置Digital Ocean负载均衡器,开启WebSocket支持并启用粘性会话(Sticky Sessions),确保同一客户端的长连接始终路由到同一worker进程,避免连接中断。
内容的提问来源于stack exchange,提问作者Hero AllMight
相关产品推荐
相关产品推荐

