nodeJS进程管理器pm2的使用


Posted in NodeJs onJanuary 09, 2019

pm2是一个带有负载均衡功能的Node应用的进程管理器。当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载, PM2是完美的。

PM2是开源的基于Nodejs的进程管理器,包括守护进程,监控,日志的一整套完整的功能,基本是Nodejs应用程序不二的守护进程选择,事实上它并不仅仅可以启动Nodejs的程序,只要是一般的脚本的程序它同样可以胜任。

主要特性:

  • 内建负载均衡(使用Node cluster 集群模块)
  • 后台运行
  • 0秒停机重载(这项功能允许你重新载入代码而不用失去请求连接。)
  • 具有Ubuntu和CentOS 的启动脚本
  • 停止不稳定的进程(避免无限循环)
  • 控制台检测
  • 提供 HTTP API
  • 远程控制和实时的接口API ( Nodejs 模块,允许和PM2进程管理器交互 )

使用环境:

  • 仅能用于web应用
  • 运行于Node 0.11.x版本
  • 运行于 cluster 模式(默认模式)

安装

npm install -g pm2

pm2安装好后,会自动创建下面目录:

/.pm2 
/.pm2/logs  
/.pm2/pids 
/.pm2/pm2.log 
/.pm2/pm2.pid 
/.pm2/rpc.sock 
/.pm2/pub.sock 
/.pm2/conf.js

用法

npm install pm2 -g          # 命令行安装 pm2 
pm2 start app.js -i 4        #后台运行pm2,启动4个app.js 
                        # 也可以把'max' 参数传递给 start
                        # 正确的进程数目依赖于Cpu的核心数目
pm2 start app.js --name my-api # 命名进程
pm2 list                 # 显示所有进程状态
pm2 monit                # 监视所有进程
pm2 logs                 # 显示所有进程日志
pm2 stop all               # 停止所有进程
pm2 restart all             # 重启所有进程
pm2 reload all              # 0秒停机重载进程 (用于 NETWORKED 进程)
pm2 stop 0                # 停止指定的进程
pm2 restart 0              # 重启指定的进程
pm2 startup               # 产生 init 脚本 保持进程活着
pm2 web                 # 运行健壮的 computer API endpoint (http://localhost:9615)
pm2 delete 0               # 杀死指定的进程
pm2 delete all              # 杀死全部进程

运行进程的不同方式:

$ pm2 start app.js -i max # 根据有效CPU数目启动最大进程数目
$ pm2 start app.js -i 3   # 启动3个进程
$ pm2 start app.js -x    #用fork模式启动 app.js 而不是使用 cluster
$ pm2 start app.js -x -- -a 23  # 用fork模式启动 app.js 并且传递参数 (-a 23)
$ pm2 start app.js --name serverone # 启动一个进程并把它命名为 serverone
$ pm2 stop serverone    # 停止 serverone 进程
$ pm2 start app.json    # 启动进程, 在 app.json里设置选项
$ pm2 start app.js -i max -- -a 23          #在--之后给 app.js 传递参数
$ pm2 start app.js -i max -e err.log -o out.log # 启动 并 生成一个配置文件
你也可以执行用其他语言编写的app ( fork 模式):
$ pm2 start my-bash-script.sh  -x --interpreter bash
$ pm2 start my-python-script.py -x --interpreter python

pm2 list

列出由pm2管理的所有进程信息,还会显示一个进程会被启动多少次,因为没处理的异常。

nodeJS进程管理器pm2的使用

pm2 monit

监视每个node进程的CPU和内存的使用情况。

nodeJS进程管理器pm2的使用

入门教程

挑我们最爱的express应用来举例。一般我们都是通过npm start启动应用,其实就是调用node ./bin/www。那么,换成pm2就是

pm2 start ./bin/www ?watch

这里用了?watch参数,意味着当你的express应用代码发生变化时,pm2会帮你重启服务。

参数说明:

--watch:监听应用目录的变化,一旦发生变化,自动重启。如果要精确监听、不见听的目录,最好通过配置文件。
-i --instances:启用多少个实例,可用于负载均衡。如果-i 0或者-i max,则根据当前机器核数确定实例数目。
--ignore-watch:排除监听的目录/文件,可以是特定的文件名,也可以是正则。比如--ignore-watch="test node_modules "some scripts""
-n --name:应用的名称。查看应用信息的时候可以用到。
-o --output <path>:标准输出日志文件的路径。
-e --error <path>:错误输出日志文件的路径。
--interpreter <interpreter>:the interpreter pm2 should use for executing app (bash, python...)。比如你用的coffee script来编写应用。

完整命令行参数列表:

pm2 start app.js ?watch -i 2

配置文件

  1. 配置文件里的设置项,跟命令行参数基本是一一对应的。
  2. 可以选择yaml或者json文件,就看个人洗好了。
  3. json格式的配置文件,pm2当作普通的js文件来处理,所以可以在里面添加注释或者编写代码,这对于动态调整配置很有好处。
  4. 如果启动的时候指定了配置文件,那么命令行参数会被忽略。(个别参数除外,比如--env)

举个简单例子:

{ 
  "name" : "fis-receiver",        // 应用名称 
  "script" : "./bin/www",         // 实际启动脚本 
  "cwd" : "./",              // 当前工作路径 
  "watch": [               // 监控变化的目录,一旦变化,自动重启 
    "bin", "routers" 
  ], 
  "ignore_watch" : [           // 从监控目录中排除 
    "node_modules", "logs", "public"
  ], 
  "watch_options": { 
    "followSymlinks": false 
  }, 
  "error_file" : "./logs/app-err.log",  // 错误日志路径 
  "out_file" : "./logs/app-out.log",   // 普通日志路径 
  "env": { 
    "NODE_ENV": "production"      // 环境变量,object类型,如{"NODE_ENV":"production", "ID": "42"};
  },
  "instances" : "max",          // 开启进程数,可为数值,也可为max。与服务器cpu核数相关。应用启动实例个数,仅在cluster模式有效,默认为fork;
  "exec_mode" : "cluster"         // 应用启动模式,支持fork和cluster模式;cluster(多核推荐)
  "min_uptime": "60s",          // 应用运行少于时间被认为是异常启动;
  "max_restarts": 30,           // 最大异常重启次数,即小于min_uptime运行时间重启次数;
  "max_memory_restart": "300M",      // 最大内存限制数,超出自动重启;
  "autorestart": true,          // 默认为true, 发生异常的情况下自动重启;
}

自定义启动文件,创建一个test.json的示例文件,格式如下:

{
 "apps":[
  {
   "name": "test",
   "cwd": "/data/wwwroot/nodejs",
   "script": "./test.sh",
   "exec_interpreter": "bash",
   "min_uptime": "60s",
   "max_restarts": 30,
   "exec_mode" : "cluster_mode",
   "error_file" : "./test-err.log",
   "out_file": "./test-out.log",
   "pid_file": "./test.pid"
   "watch": false
  }
]}

参数说明:

  • apps:json结构,apps是一个数组,每一个数组成员就是对应一个pm2中运行的应用
  • name:应用程序的名称
  • cwd:应用程序所在的目录
  • script:应用程序的脚本路径
  • exec_interpreter:应用程序的脚本类型,这里使用的shell,默认是nodejs
  • min_uptime:最小运行时间,这里设置的是60s即如果应用程序在60s内退出,pm2会认为程序异常退出,此时触发重启max_restarts设置数量
  • autorestart 默认为true, 发生异常的情况下自动重启;
  • max_restarts:设置应用程序异常退出重启的次数,默认15次(从0开始计数)
  • exec_mode:应用程序启动模式,这里设置的是cluster(集群),默认是fork
  • error_file:自定义应用程序的错误日志文件
  • out_file:自定义应用程序日志文件
  • pid_file:自定义应用程序的pid文件
  • watch:是否启用监控模式,默认是false。如果设置成true,当应用程序变动时,pm2会自动重载。这里也可以设置你要监控的文件。
  • max_memory_restart:当内存超过设置的数量时自动重启。 如果工程中有比较棘手的内存泄露问题,这个算是一个折中方案。
  • instances: 启用多少个实例,可用于负载均衡。仅在cluster模式有效,默认为fork;
  • cron_restart crontab时间格式,定时重启应用,目前只支持cluster模式;

运行实例:已上面的test.json为例

pm2 start test.json

环境切换

在实际项目开发中,我们的应用经常需要在多个环境下部署,比如开发环境、测试环境、生产环境等。在不同环境下,有时候配置项会有差异,比如链接的数据库地址不同等。

对于这种场景,pm2也是可以很好支持的。首先通过在配置文件中通过env_xx来声明不同环境的配置,然后在启动应用时,通过?env参数指定运行的环境。

首先,在配置文件中,通过env选项声明多个环境配置。简单说明下:

env为默认的环境配置(生产环境),env_dev、env_test则分别是开发、测试环境。可以看到,不同环境下的NODE_ENV、REMOTE_ADDR字段的值是不同的。

在应用中,可以通过process.env.REMOTE_ADDR等来读取配置中生命的变量。

例如:

"env": { "NODE_ENV": "production","REMOTE_ADDR": "http://www.example.com/"}
"env_dev": { "NODE_ENV": "development", "REMOTE_ADDR": "http://wdev.example.com/"} 
​"env_test": { "NODE_ENV": "test", "REMOTE_ADDR": http://wtest.example.com/}

启动指明环境:假设通过下面启动脚本(开发环境),那么,此时process.env.REMOTE_ADDR的值就是相应的链接地址

pm2 start app.js --env dev

负载均衡

命令如下,表示开启三个进程。如果-i 0,则会根据机器当前核数自动开启尽可能多的进程。

m2 start app.js -i 3 # 开启三个进程 
​ 
​pm2 start app.js -i max # 根据机器CPU核数,开启对应数目的进程

日志查看

除了可以打开日志文件查看日志外,还可以通过pm2 logs来查看实时日志。这点对于线上问题排查非常重要。

比如某个node服务突然异常重启了,那么可以通过pm2提供的日志工具来查看实时日志,看是不是脚本出错之类导致的异常重启。

pm2 logs

开机自动启动

可以通过pm2 startup来实现开机自启动。大致流程如下:

通过pm2 save保存当前进程状态。

通过pm2 startup [platform]生成开机自启动的命令。(记得查看控制台输出)

将步骤2生成的命令,粘贴到控制台进行,搞定。

自动重启应用

fork不支持定时重启,cluster支持定时重启。定时重启也就是配置中的cron_restart配置项。

监控(monitor)

运行如下命令,查看当前通过pm2运行的进程的状态。

pm2 monit

内存使用超过上限自动重启

如果想要你的应用,在超过使用内存上限后自动重启,那么可以加上?max-memory-restart参数。(有对应的配置项)

pm2 start big-array.js ?max-memory-restart 20M

Web API

如果你不仅仅想监控被pm2管理的进程,还需要监控进程所运行的机器的信息,你可以使用下面这个API。

pm2 web

pm2会启动一个叫做pm2-http-interface的进程提供web服务。你打开浏览器输入http://127.0.0.1:9615,是不是被看到的结果惊艳到了。

nodeJS进程管理器pm2的使用

pm2与forever对比

Feature Forever PM2
Keep Alive
Coffeescript  
Log aggregation  
API  
Terminal monitoring  
Clustering  
JSON configuration  

稳定运行建议

PM2是一款非常优秀的Node进程管理工具,它有着丰富的特性:能够充分利用多核CPU且能够负载均衡、能够帮助应用在崩溃后、指定时间(cluster model)和超出最大内存限制等情况下实现自动重启。

个人几点看法保证常驻应用进程稳定运行:

  • 定时重启,应用进程运行时间久了或许总会产生一些意料之外的问题,定时可以规避一些不可测的情况;
  • 最大内存限制,根据观察设定合理内存限制,保证应用异常运行;
  • 合理min_uptime,min_uptime是应用正常启动的最小持续运行时长,超出此时间则被判定为异常启动;
  • 设定异常重启延时restart_delay,对于异常情况导致应用停止,设定异常重启延迟可防止应用在不可测情况下不断重启的导致重启次数过多等问题;
  • 设置异常重启次数,如果应用不断异常重启,并超过一定的限制次数,说明此时的环境长时间处于不可控状态,服务器异常。此时便可停止尝试,发出错误警告通知等。

与supervisor对比

supervisor可以实现修改命令后重启应用,但是关闭控制台之后,整个进程就挂了。pm2则可以后台运行,关闭控制台之后也不影响进程运行。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
基于promise.js实现nodejs的promises库
Jul 06 NodeJs
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
Sep 26 NodeJs
Nodejs如何复制文件
Mar 09 NodeJs
Nodejs进阶:基于express+multer的文件上传实例
Nov 21 NodeJs
Nodejs基于LRU算法实现的缓存处理操作示例
Mar 17 NodeJs
nodejs操作mysql实现增删改查的实例
May 28 NodeJs
深入解析nodejs HTTP服务
Jul 25 NodeJs
nodejs读取并去重excel文件
Apr 22 NodeJs
详解Nodejs mongoose
Jun 10 NodeJs
nodejs更新package.json中的dependencies依赖到最新版本的方法
Oct 10 NodeJs
搭建一个nodejs脚手架的方法步骤
Jun 28 NodeJs
浅谈使用nodejs搭建web服务器的过程
Jul 20 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 #NodeJs
nodejs 使用http进行post或get请求的实例(携带cookie)
Jan 03 #NodeJs
详解nodejs 配置文件处理方案
Jan 02 #NodeJs
nodejs基础之多进程实例详解
Dec 27 #NodeJs
nodejs基础之常用工具模块util用法分析
Dec 26 #NodeJs
nodejs基础之buffer缓冲区用法分析
Dec 26 #NodeJs
nodejs异步编程基础之回调函数用法分析
Dec 26 #NodeJs
You might like
php 采集书并合成txt格式的实现代码
2009/03/01 PHP
PHP父类调用子类方法的代码例子
2014/04/09 PHP
php实现上传图片文件代码
2015/07/19 PHP
JSON字符串传到后台PHP处理问题的解决方法
2016/06/05 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
JQuery插件fancybox无法在弹出层使用左右键的解决办法
2013/12/25 Javascript
jQuery中:image选择器用法实例
2015/01/03 Javascript
JavaScript代码里的判断小结
2016/08/22 Javascript
jQuery validate插件功能与用法详解
2016/12/15 Javascript
js获取当前页的URL与window.location.href简单方法
2017/02/13 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
2017/09/18 jQuery
vue-cli 引入jQuery,Bootstrap,popper的方法
2018/09/03 jQuery
说说Vuex的getters属性的具体用法
2019/04/15 Javascript
JS基础之逻辑结构与循环操作示例
2020/01/19 Javascript
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
NodeJS和浏览器中this关键字的不同之处
2021/03/03 NodeJs
在pycharm上mongodb配置及可视化设置方法
2018/11/30 Python
Python爬取数据保存为Json格式的代码示例
2019/04/09 Python
新手如何发布Python项目开源包过程详解
2019/07/11 Python
Django 实现将图片转为Base64,然后使用json传输
2020/03/27 Python
python爬取2021猫眼票房字体加密实例
2021/02/19 Python
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
理肤泉英国官网:La Roche-Posay英国
2019/01/14 全球购物
应届毕业生专业个人求职自荐信格式
2013/11/20 职场文书
结构工程个人自荐信范文
2013/11/30 职场文书
《临死前的严监生》教学反思
2014/02/13 职场文书
对祖国的寄语大全
2014/04/11 职场文书
党员转正大会主持词
2015/07/02 职场文书
婚礼双方父亲致辞
2015/07/27 职场文书
感恩教育主题班会
2015/08/12 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
导游词书写之黄山
2019/08/06 职场文书
详解MySql中InnoDB存储引擎中的各种锁
2022/02/12 MySQL
Java实现学生管理系统(IO版)
2022/02/24 Java/Android
在容器中使用nginx搭建上传下载服务器
2022/05/11 Servers
让JavaScript代码更加精简的方法技巧
2022/06/01 Javascript