pm2使用以及node中的进程线程的了解

node中的线程进程及pm2的使用

进程

进程 process是系统进行资源分配和调度的基本单位,是操作系统结构的基础,进程是线程的容器(来自百科)。进程是资源分配的最小单位。我们启动一个服务、运行一个实例,就是开一个服务进程

如下就是一个node进程:

const http = require('http')

const server = http.createServer();

server.listen(3000, ()=>{
  console.log('进程id', process.pid)
})

线程

线程是操作系统能够进行运算调度的最小单位,首先我们要清楚线程是隶属于进程的,被包含于进程之中。一个线程只能隶属于一个进程,但是一个进程是可以拥有多个线程的

单线程

单线程就是一个进程只开一个线程

Javascript 就是属于单线程,程序顺序执行(这里暂且不提JS异步),可以想象一下队列,前面一个执行完之后,后面才可以执行,当你在使用单线程语言编码时切勿有过多耗时的同步操作,否则线程会造成阻塞,导致后续响应无法处理。你如果采用 Javascript 进行编码时候,请尽可能的利用Javascript异步操作的特性。

    • Node.js 虽然是单线程模型,但是其基于事件驱动、异步非阻塞模式,可以应用于高并发场景,避免了线程创建、线程之间上下文切换所产生的资源开销。
    • 当你的项目中需要有大量计算,CPU 耗时的操作时候,要注意考虑开启多进程来完成了。
    • Node.js 开发过程中,错误会引起整个应用退出,应用的健壮性值得考验,尤其是错误的异常抛出,以及进程守护是必须要做的。
    • 单线程无法利用多核CPU,但是后来Node.js 提供的API以及一些第三方工具(pm2)相应都得到了解决

Node.js 进程创建

    • child_process.spawn():适用于返回大量数据,例如图像处理,二进制数据处理。
    • child_process.exec():适用于小量数据,maxBuffer 默认值为 200 * 1024 超出这个默认值将会导致程序崩溃,数据量过大可采用 spawn。
    • child_process.execFile():类似 child_process.exec(),区别是不能通过 shell 来执行,不支持像 I/O 重定向和文件查找这样的行为
    • child_process.fork():衍生新的进程,进程之间是相互独立的,通常根据系统* CPU 核心数*设置

fork开启子进程 Demo

const http = require('http')
const fork = require('child_process').fork

const server = http.createServer((req, res) =>{
  if (req.url === '/demo') {
    const son = fork("./son.js")
    son.send('开启一个子进程')
    
    // 当一个子进程使用 process.send() 发送消息时会触发 ‘message’事件
    son.on('message', ()=>{
      son.kill()
    })
    // 子进程监听到错误退出终止
    son.on('close', () =>{
      son.kill()
    })
  }
})

server.listen(8086)

cluster模块创建子进程

const cluster = require('cluster');
const os = require('os');

if (cluster.isMaster) {
  for (var i = 0, n = os.cpus().length; i < n; i += 1) {
    cluster.fork();
  }
} else {
   // 启动程序 
}

Node.js 进程守护

进程守护是?

每次启动 Node.js 程序都需要在命令窗口输入命令 node app.js 才能启动,但如果把命令窗口关闭则Node.js 程序服务就会立刻断掉。当我们这个 Node.js 服务意外崩溃了就不能自动重启进程了。执行 node app.js 开启一个服务进程之后,我还可以在这个终端上做些别的事情,且不会相互影响,当出现问题可以自动重启。

 

如何实现进程守护

第三方的进程守护框架,pm2 和 forever ,它们都可以实现进程守护,底层也都是通过上面讲的 child_process 模块和 cluster 模块实现的


pm2常用api

$ pm2 start app.js -i 4  # 后台运行pm2,启动4个app.js

$ pm2 list               # 显示所有进程状态

$ pm2 monit       # 监视所有进程

$ pm2 logs        # 显示所有进程日志

$ pm2 reload all/app_name   # 0秒停机重载进程,会算在服务重启的次数中,类似于平滑重启

$ pm2 restart id/all/app_name # 会重新加载代码,因为需要杀掉原有进程,所以服务会中断

$ pm2 stop id/all/app_name  # 停止指定名称的进程,如果是一个名称多进程,则一起停止,不会释放端口

$ pm2 delete id/all/app_name # 删除指定名称的进程,如果是一个名称多进程,则一起删除,不会释放端口

$ pm2 kill  # 杀掉所有pm2进程并释放资源,包含pm2自身,会释放端口

通过json文件配置文件启动服务

 {
    "apps": {
        "name": "xbb",                             // 项目名          
        "script": "./bin/node",                      // 执行文件
        "cwd": "./",                                // 根目录
        "watch": true,                              // 是否监听文件变动然后重启
        "ignore_watch": [                           // 不用监听的文件
            "node_modules",
            "logs"
        ],
        "exec_mode": "cluster_mode",                // 应用启动模式,支持fork和cluster模式
        "instances": 4,                             // 应用启动实例个数,仅在cluster模式有效 默认为fork;或者 max
        "max_memory_restart": 8,                    // 最大内存限制数,超出自动重启
        "error_file": "./logs/app-err.log",         // 错误日志文件
        "out_file": "./logs/app-out.log",           // 正常日志文件
     
        "min_uptime": "60s",                        // 应用运行少于时间被认为是异常启动
        "max_restarts": 30,                         // 最大异常重启次数,即小于min_uptime运行时间重启次数;
        "autorestart": true,                        // 默认为true, 发生异常的情况下自动重启
        "cron_restart": "",                         // crontab时间格式重启应用,目前只支持cluster模式;
        "restart_delay": "60s"                      // 异常重启情况下,延时重启时间
        "env": {
           "NODE_ENV": "production",                // 环境参数,当前指定为生产环境 process.env.NODE_ENV
           "REMOTE_ADDR": "xbb"               // process.env.REMOTE_ADDR
        },
        "env_dev": {
            "NODE_ENV": "development",              // 环境参数,当前指定为开发环境 pm2 start app.js --env_dev
            "REMOTE_ADDR": ""
        },
        "env_test": {                               // 环境参数,当前指定为测试环境 pm2 start app.js --env_test
            "NODE_ENV": "test",
            "REMOTE_ADDR": ""
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/chengeping/p/11756920.html