前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs实现多进程

nodejs实现多进程

原创
作者头像
conanma
发布2022-01-04 18:10:01
8700
发布2022-01-04 18:10:01
举报
文章被收录于专栏:正则

Nodejs的主进程是单线程的,但它有多线程处理方案(更准备来说是多进程方案),即主进程开启不同的子进程,主进程接收所有请求,然后将分发给其它不同的nodejs子进程处理。

它一般有两种实现:

  1. 主进程监听一个端口,子进程不监听端口,通过主进程分发请求到子进程;
  2. 主进程和子进程分别监听不同端口,通过主进程分发请求到子进程。

cluster模式

Nodejscluster模式用的就是第一种实现,它使用一个主线程master和多个子线程worker,形成一个集群,通过主线程来向子线程分发请求。cluster 实现了对 child_process 的封装,通过 fork 方法创建子进程的方式实现了多进程模型。

cluster的使用

httpclusterprocess都是nodejs的内置模块,不需要额外安装

  1. 创建一个http服务
代码语言:javascript
复制
// http是nodejs内置模块
const http = require('http')

const server = http.createServer((req, res) => {
  res.write('hello http!')
  res.end()
})

server.listen(3030, () => {
  console.log('server is listening on http://localhost:3030')
})

// process是node的进程模块,可以从这个模块获取进程的信息,以及控制进程的
console.log(`worker ${process.pid} start`)
  1. 创建cluster 在下面程序中,会首先判断有没有主进程,如果没有,就创建进程,它会默认第一个进程为主进程
  • 在源码中,是调用cluster.fork()方法时,会执行setupPrimary方法创建主进程,它会使用initialized标识是否为true会判断是否为首次创建,如果是就创建主进程,否则就跳过
  • 使用createWorkerProcess来创建子进程,这个方法实际是使用child_process来创建子进程的
代码语言:javascript
复制
const cluster = require('cluster')
// 开启的子进程数
const workerNum = 3;
// 如果是主进程
if(cluster.isMaster) {
  // 创建子进程
  for(let i = 0; i < workerNum; i++) {
    // 通过cluster.fork创建子进程
    cluster.fork()
  }
// 如果有子进程,就启动相关服务,这里会使用三个进程来执行http服务演示
}else {
  require('./http-server')
}

实现过程大概是这样的: cluster 模块应用 child_process 来创建子进程,子进程通过复写掉 cluster._getServer 方法,从而在 server.listen 来保证只有主进程监听端口,主子进程通过 IPC进行通信,其次主进程根据平台或者协议不同,应用两种不同模块(round_robin_handle.jsshared_handle.js)进行请求分发给子进程处理。

PM2

PM2是后台进程管理器,是多进程方案的一个成熟应用,可以帮助管理和保持应用程序在线。

基本使用

全局安装:npm install pm2@latest -g 它的使用也非常简单:

  • 开启(http-server.js是要启动的程序):pm2 start http-server.js
  • 重启(程序):restart app_name
  • 重载(配置和程序):reload app_name
  • 停止:pm2 stop app_name
  • 删除:pm2 delete app_name
  • 监听模式:pm2 start xx.js --watch

负载均衡:

PM2对nodejs应用,可以根据系统自动实现负载均衡:pm2 start http-server.js -i max

PM2配置

我们肯定不想每次启动时,都要手动输入一堆指令,所以我们可以将这些配置统一使用配置文件来管理,注意js文件名必须是 xxx.config.js,我这里用ecosystem.config.jsapps数组中,可以放置多个对象,对应多个文件执行不同的配置

代码语言:javascript
复制
// ecosystem.config.js
module.exports = {
  apps : [{
    name: "http-server", // 启动进程名
    script: "./src/http-server.js", // 启动文件
    instances: 4, // 启动进程数
    exec_mode: 'cluster', // 多进程多实例
    // 设置不同环境的环境配置
    // 开发环境,对应--env 后的参数
    env_development: {
      NODE_ENV: "dev",
      watch: true, // 开发环境使用 true,其他设置为 false
    },
    // 测试环境
    env_testing: {
      NODE_ENV: "test",
      watch: false, // 开发环境使用 true,其他设置为 false
    },
    // 生产环境
    env_production: {
      NODE_ENV: "prod",
      watch: false, // 开发环境使用 true,其他必须设置为 false
    },
    // 日志日期格式
    log_date_format: 'YYYY-MM-DD HH:mm Z',
    // 错误日志文件,必须设置在项目外的目录,这里为了测试
    error_file: '~/Desktop/logs/err.log', 
    //  流水日志,包括 console.log 日志,必须设置在项目外的目录,这里为了测试
    out_file: '~/Desktop/logs/info.log', 
    // 最大重启数据,当应用被认定连续n次不稳定重启起,再重启
    max_restarts: 10,
  },{
    name: "express-test", // 启动进程名
    script: "./src/express-test.js", // 启动文件
    instances: 4, // 启动进程数
    exec_mode: 'cluster', // 多进程多实例
  }]
}

执行配置:pm2 start ecosystem.config.js --env dev

可以看到在启动后,桌面上生成了流水和错误日志:

日志

流水日志

参考: Node Process模块 API:http://nodejs.cn/api/process.html pm2官网: https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • cluster模式
    • cluster的使用
    • PM2
      • 基本使用
        • 负载均衡:
        相关产品与服务
        负载均衡
        负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档