概述
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 # 停止指定名称的进程,如果是一个名称多进程,则一起停止,不会释放端口
$ pm2delete 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": ""
}
}
}
最后
以上就是彪壮大船为你收集整理的node开启子线程_pm2使用以及node中的进程线程的了解的全部内容,希望文章能够帮你解决node开启子线程_pm2使用以及node中的进程线程的了解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复