PM2 集群模式启动 TCP 服务:从 ecosystem 配置到 Node 负载均衡原理
运维CLI可观测性【免费下载链接】pm2Node.js/Typescript/Bun Production Process Manager with a built-in Load Balancer.项目地址https://gitcode.com/gh_mirrors/pm/pm2点击查看免费下载导读本篇文章围绕 PM2 仓库中examples/cluster-tcp示例讲解如何用 PM2 以集群模式cluster mode启动一个基于 Node.jsnet模块的 TCP 服务。你将掌握两种启动方式ecosystem 配置文件与命令行-i max、process.config.js中 cluster/fork 两种运行模式的差异、NODE_APP_INSTANCE实例编号的注入机制以及 PM2 底层如何通过 Nodecluster模块实现负载均衡并最终能独立完成 TCP 长连接服务的多进程部署与验证。示例概览cluster-tcp 目录结构在仓库根目录下的 examples/cluster-tcp 中包含四个文件tcp.js基于net模块的 TCP 服务器是本次集群化部署的核心应用process.config.jsecosystem 配置文件同时定义了 cluster 与 fork 两种运行模式的实例http.js同目录下的 HTTP 对比示例用于直观对比 HTTP 与 TCP 两类服务的集群化差异README.md示例的启动说明原文如下To start tcp application in cluster mode:$ pm2 start ecosystem.config.js # OR $ pm2 start tcp.js -i max下文将围绕这两条命令逐步展开先剖析应用代码与配置文件再追踪底层实现最后给出完整可复现的验证流程。第一步阅读 TCP 应用代码 tcp.jstcp.js 的完整实现如下var net require(net); var server net.createServer(function (socket) { socket.write(Welcome to the Telnet server of the process (process.env.NODE_APP_INSTANCE || must be run on pm2)); }).listen(process.env.PORT || 8888, function() { console.log(Listening on port %s, server.address().port); });这段代码有三处为 PM2 集群化量身设计的关键点端口取自环境变量process.env.PORT || 8888。应用本身不硬编码端口而是由 PM2 在启动时注入PORT环境变量或回退到默认端口 8888。这使同一个脚本可以被多个实例以不同端口运行是实现“多实例不冲突”的前提。实例编号标识process.env.NODE_APP_INSTANCE是 PM2 为每个集群实例自动注入的编号从 0 开始。示例用它把欢迎语输出为 process0、process1 等方便在客户端直接辨认当前连接的是哪个实例。连接即写回每当有客户端建立连接服务器立即向 socket 写入一行欢迎信息。配合telnet或nc即可无代码验证集群分配效果。第二步两种启动方式按示例 README启动集群模式的 TCP 应用有两种等价方式# 方式一通过 ecosystem 配置文件启动 $ pm2 start ecosystem.config.js # 方式二直接指定脚本与实例数 $ pm2 start tcp.js -i max两种方式的语义相同以集群模式启动实例数取 CPU 核心数。区别在于方式一面向“可交付、可复用”的场景所有应用级配置名称、实例数、运行模式、环境变量、日志路径等固化在配置文件中团队成员共享同一份配置即可保证部署一致方式二面向“快速验证”的场景适合临时起一个进程做冒烟测试-i等价于--instances参数直接指定实例数量。关于instances参数的语义可参考 lib/API/schema.jsoninstances: { type: number, docDefault: 1, docDescription: Number of instances to be started in cluster mode }即不指定时默认 1 个实例传入max时 PM2 会按可用 CPU 数量展开。此处exec_mode未显式指定时默认走 fork 模式只有配置了 cluster 模式或命令行带-i才会走集群分支。第三步剖析 process.config.jscluster 与 fork 同台对比process.config.js 是本示例的精华所在它同时声明了两个应用module.exports { apps : [{ name : clustered_tcp, script : ./tcp.js, instances : max, exec_mode : cluster, env : { PORT : 8002 } }, { name : forked_tcp, script : ./tcp.js, env : { PORT : 8001 } }] }逐项解读字段clustered_tcpforked_tcp说明nameclustered_tcpforked_tcp进程在pm2 ls中显示的名字也是日志文件前缀script./tcp.js./tcp.js同一个脚本两种模式对比instancesmax未设置默认 1集群实例数量max表示铺满全部 CPU 核心exec_modecluster未设置默认 fork运行模式决定底层走 Nodecluster还是独立进程env.PORT80028001为每个应用注入独立端口避免多实例端口冲突这个文件展示了一个非常实用的调试技巧同一个 TCP 服务用 cluster 和 fork 两种模式同时跑在不同端口上。客户端分别连接8001、8002端口即可直观对比两种模式的行为差异例如 fork 模式每个进程各自独占监听端口而 cluster 模式多个 worker 共享同一端口由 master 分发。第四步底层原理——PM2 如何实现集群化PM2 的 cluster 与 fork 两种模式在源码中由两个模块分别实现4.1 cluster 模式God.nodeApplib/God/ClusterMode.js 中的God.nodeApp是集群模式的入口。核心动作只有一行——调用 Node 原生cluster.forkvar cluster require(cluster); God.nodeApp function nodeApp(env_copy, cb){ // 透传 node_args 到 cluster.settings.execArgv if (env_copy.node_args Array.isArray(env_copy.node_args)) { cluster.settings.execArgv env_copy.node_args; } // 环境信息以 JSON 字符串形式传给 fork 出的子进程 clu cluster.fork({pm2_env: JSON.stringify(env_copy), windowsHide: true}); // ... };从源码结构可以推断出 PM2 集群模式的核心机制PM2 的 DaemonGod扮演 Node cluster 的 master 角色由它fork出 N 个 workerNode 内置的负载均衡器把到达 master 监听端口的连接按轮询round-robin非 Windows 平台默认分发给各 worker。这正是 PM2 自述 built-in Load Balancer 的落地点。此外源码特意将pm2_env序列化为 JSON 字符串再传入注释解释了 Node cluster 在 fork 进程间传递嵌套对象时会被 toString 化导致args/env结构损坏这是保证 PM2 元数据在 worker 中完整还原的实现细节。4.2 fork 模式God.forkModelib/God/ForkMode.js 的God.forkMode则是另一条路径它通过child_process.spawn以独立进程方式拉起应用。关键逻辑if (interpreter node || RegExp(node$).test(interpreter)) { args.push(path.resolve(..., ProcessContainerFork.js)); }即 fork 模式下 PM2 并不是直接执行用户的tcp.js而是先启动一个包装脚本 lib/ProcessContainerFork.js可选启用 source map 支持、注入自定义模块、发送 node_version 上报再通过require(module)._load(process.env.pm_exec_path, null, true)加载真实应用。这也是 fork 模式进程标题被改写为node pm_exec_path的原因。4.3 两种模式的对比要点维度cluster 模式fork 模式底层机制Nodecluster.forkmaster 统一分发连接child_process.spawn独立进程负载均衡由 Node 内置 Load Balancer 提供无需外部负载均衡器端口占用多 worker 共享同一监听端口各进程需独立端口本例用 PORT 区分适用场景HTTP / 无状态 TCP 服务有状态服务、非常规解释器、需要隔离的场景源码入口lib/God/ClusterMode.jslib/God/ForkMode.js第五步NODE_APP_INSTANCE 是怎么注入的tcp.js 中读取的NODE_APP_INSTANCE由 PM2 在启动每个实例前统一注入实现在 lib/God.js 的God.injectVariables// 允许通过 instance_var 或环境变量覆盖实例编号的键名 var instanceKey process.env.PM2_PROCESS_INSTANCE_VAR || env.instance_var; // 收集同名应用中已使用的实例编号 var instances Object.keys(God.clusters_db) .map(...) .filter(function (proc) { return proc.pm2_env.name env.name ...; }).map(function (proc) { return proc.pm2_env[instanceKey]; }).sort(function (a, b) { return b - a; }); // 默认取 最大编号 1并优先复用空缺编号 var instanceNumber typeof instances[0] undefined ? 0 : instances[0] 1; for (var i 0; i instances.length; i) { if (instances.indexOf(i) -1) { instanceNumber i; break; } } env[instanceKey] instanceNumber;要点编号从 0 开始按同名字应用内的“已用编号 1”递增并会复用因重启、删除而空出来的编号键名默认为NODE_APP_INSTANCE可以通过配置instance_var改名见 lib/API/schema.json 中的instance_var字段默认值为NODE_APP_INSTANCE若同时配置了increment_varPM2 还会注入一个按实例递增的自定义变量schema 中描述为 “inject which increments for each cluster”适合需要每个实例拿到不同编号做分片等场景。第六步启动、验证与运维启动$ cd examples/cluster-tcp $ pm2 start ecosystem.config.js # 或快速启动单个应用铺满 CPU $ pm2 start tcp.js -i max验证集群分配pm2 ls应能看到clustered_tcp展开为多个实例编号 0、1、2…forked_tcp为单实例。使用终端客户端连接验证# 连接集群模式实例端口 8002 $ telnet localhost 8002 # 或 $ nc localhost 8002每次新建立连接时欢迎语中的实例编号process0 / process1 / …会轮换说明连接被 Node 内置负载均衡器分发到了不同 worker。查看各实例日志可进一步确认$ pm2 logs clustered_tcp日志中的 Listening on port 8002 会来自多个不同 PID 的实例但所有 worker 共享同一个监听端口这正是 cluster 模式与 fork 模式的直观差异。运维提示pm2 reload/pm2 restart均可作用于集群应用滚动重启时 Node 的 cluster 机制会逐个替换 worker最大限度降低连接中断集群模式下日志默认按实例拆分可通过merge_logs: true合并见 lib/API/schema.json 中merge_logs字段说明若应用需要固定的外部端口如防火墙白名单可像本示例一样为每个实例注入独立PORT或仅在 cluster 模式中使用单个共享端口。第七步TCP 集群化的注意事项HTTP 与 TCP 在集群化上的一个重要差异值得说明Node 内置负载均衡器对 HTTP 这类短连接、无状态的请求分发非常理想而对于 TCP 长连接连接一旦建立就会固定绑定到某个 worker。因此无状态协议如文本协议、命令响应式服务可直接套用本示例的集群模式有状态协议如需要会话保持的协议需自行在应用层设计粘性会话或共享存储Node 集群机制本身不提供会话保持跨机器水平扩展时Node 内置集群仅覆盖单机多核多机场景仍需外置负载均衡如 LVS、HAProxy 等配合。从当前仓库源码看PM2 集群模式的职责边界正是“单机多核 Node 原生 cluster”这一定位在 lib/God/ClusterMode.js 的注释中也有体现It will wrap the code and enable load-balancing mode。小结通过examples/cluster-tcp示例你可以得到一条完整的 TCP 服务集群化链路配置层用 process.config.js 声明exec_mode: cluster与instances: max用env.PORT区分实例代码层应用通过process.env.PORT与process.env.NODE_APP_INSTANCE感知环境无需任何 PM2 相关依赖原理层lib/God/ClusterMode.js 调用 Nodecluster.fork实现 worker 展开与内置负载均衡lib/God.js 负责实例编号注入验证层pm2 ls、pm2 logs加telnet/nc客户端即可确认多实例轮询分发。如需进一步对比同目录的 http.js 提供了 HTTP 版集群示例监听process.env.PORT || 8000而仓库中更完整的 HTTP 集群演示可参考 examples/cluster-http两相对照即可全面掌握 PM2 的进程管理与负载均衡能力。赞分享运维CLI可观测性【免费下载链接】pm2Node.js/Typescript/Bun Production Process Manager with a built-in Load Balancer.项目地址https://gitcode.com/gh_mirrors/pm/pm2点击查看免费下载相关推荐Conan服务器水平扩展负载均衡与集群配置Conan服务器水平扩展负载均衡与集群配置 为什么需要Conan服务器集群 随着团队规模扩大和项目复杂度提升单一Conan服务器面临三大挑战并发请求瓶颈开发工具包管理器构建工具CLILearn GDScript From Zero社区贡献指南如何参与翻译和代码开发Learn GDScript From Zero社区贡献指南如何参与翻译和代码开发 Learn GDScript From Zero是一个帮助新手从零开始学习人工智能AI 应用桌面应用代码智能体Meshery跨集群服务发现DNS配置与负载均衡策略Meshery跨集群服务发现DNS配置与负载均衡策略 在云原生环境中随着Kubernetes集群数量的增长跨集群服务发现成为保障微服务通信的关键挑战。传统云原生微服务运维DevOps上一篇Laravel Boost终极指南15 MCP工具加速AI辅助开发下一篇DeepSeek Harness 模型提供方配置指南从官方路由、目录提供方到自定义网关与兼容性调优创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于 internal-comms Skill 编写全公司 FAQ 回复指南:从信号采集到问答成文的完整流程

基于 internal-comms Skill 编写全公司 FAQ 回复指南:从信号采集到问答成文的完整流程

人工智能AI 技能AI 评测 【免费下载链接】skills Public repository for Agent Skills 项目地址: https://gitcode.com/GitHub_Trending/skills3/skills 点击查看 免费下载 公司内部沟通中,FAQ 回复是最能直接降低全员工信息差、消除重复提问焦虑的文档…

2026/9/30 1:48:24 阅读更多 →
大模型多语言数学与逻辑评测基准:跨语言多步推导的综合 Leaderboard 自动化构建

大模型多语言数学与逻辑评测基准:跨语言多步推导的综合 Leaderboard 自动化构建

大模型多语言数学与逻辑评测基准:跨语言多步推导的综合 Leaderboard 自动化构建在大语言模型(LLM)从实验室预训练走向商业化交付与跨国多语言能力验收的最后关键战役中,研发委员会面临着一个极其严肃的**“全景能力权威综合仲裁命…

2026/9/30 1:48:24 阅读更多 →
SeaweedFS 远端对象缓存(Remote Object Cache)集成测试全解析:从 Write–Uncache–Read 流程到 Singleflight 去重与 68 个测试用例

SeaweedFS 远端对象缓存(Remote Object Cache)集成测试全解析:从 Write–Uncache–Read 流程到 Singleflight 去重与 68 个测试用例

分布式文件系统对象存储存储 【免费下载链接】seaweedfs SeaweedFS is a distributed storage system for object storage (S3), file systems, and Iceberg tables, designed to handle billions of files with O(1) disk access and effortless horizontal scaling. 项目地址…

2026/9/30 1:47:23 阅读更多 →

最新新闻

FreeRTOS任务设计本质:确定性调度而非多线程

FreeRTOS任务设计本质:确定性调度而非多线程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 2:26:47 阅读更多 →
公交系统课程设计:从图建模到最短路径算法的完整实现

公交系统课程设计:从图建模到最短路径算法的完整实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 2:26:47 阅读更多 →
Android 应用安装目录与包名路径查询实战

Android 应用安装目录与包名路径查询实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 2:26:47 阅读更多 →
Automatic_ticket_purchase:Python 大麦抢票脚本,自动完成登录、票源监控与下单

Automatic_ticket_purchase:Python 大麦抢票脚本,自动完成登录、票源监控与下单

Automatic_ticket_purchase:Python 大麦抢票脚本,自动完成登录、票源监控与下单 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 热门演出开票时&#…

2026/9/30 2:26:47 阅读更多 →
【AI智能体】Codex 数据分析与处理实战项目操作详解

【AI智能体】Codex 数据分析与处理实战项目操作详解

目录 一、前言 二、Codex 介绍 2.1 Codex 是什么 2.2 Codex能做什么? 2.3 Codex 数据分析介绍 2.3.1 codex 数据分析优势 2.3.2 codex 数据分析使用场景 2.3.3 codex 数据分析上手流程 三、Codex 数据分析操作 3.1 前置准备 3.2 excel 数据分析 3.2.1 数…

2026/9/30 2:26:47 阅读更多 →
yocto: 14-product

yocto: 14-product

第4课:如果前面你已经完成了 meta-myhello,那么下一步学习 创建自己的产品 Layer(meta-myproduct) 就是 Yocto 开发真正的开始。 建议这一课的目标不要只是会创建 Layer,而是理解: 为什么要把 Board(BSP)、…

2026/9/30 2:25:47 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →