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 相关文章推荐
将nodejs打包工具整合到鼠标右键的方法
May 11 NodeJs
nodejs中实现路由功能
Dec 29 NodeJs
nodejs批量修改文件编码格式
Jan 22 NodeJs
NodeJS和BootStrap分页效果的实现代码
Nov 07 NodeJs
简单实现nodejs上传功能
Jan 14 NodeJs
NodeJs下的测试框架Mocha的简单介绍
Feb 22 NodeJs
深入nodejs中流(stream)的理解
Mar 27 NodeJs
nodejs使用express创建一个简单web应用
Mar 31 NodeJs
NodeJs之word文件生成与解析的实现代码
Apr 01 NodeJs
nodejs dgram模块广播+组播的实现示例
Nov 04 NodeJs
浅谈使用nodejs搭建web服务器的过程
Jul 20 NodeJs
NodeJS开发人员常见五个错误理解
Oct 14 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.ini中文版(2)
2006/10/09 PHP
PHP 执行系统外部命令 system() exec() passthru()
2009/08/11 PHP
基于PHP Web开发MVC框架的Smarty使用说明
2013/04/19 PHP
php读取目录所有文件信息dir示例
2014/03/18 PHP
PHP下载生成的csv文件及问题总结
2015/08/06 PHP
PHP浮点数的一个常见问题
2016/03/10 PHP
jQuery 性能优化指南(2)
2009/05/21 Javascript
JavaScript 小型打飞机游戏实现原理说明
2010/10/28 Javascript
jquery制作居中遮罩层效果分享
2014/02/21 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
javascript获得当前的信息的一些常用命令
2015/02/25 Javascript
cookie的secure属性详解
2015/04/08 Javascript
JavaScript 变量、作用域及内存
2015/04/08 Javascript
JS+CSS实现另类带提示效果的竖向导航菜单
2015/10/15 Javascript
js实现导航栏中英文切换效果
2017/01/16 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
Angular6新特性之Angular Material
2018/12/28 Javascript
JS阻止事件冒泡的方法详解
2019/08/26 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
python实现判断数组是否包含指定元素的方法
2015/07/15 Python
python实现unicode转中文及转换默认编码的方法
2017/04/29 Python
Django admin美化插件suit使用示例
2017/12/12 Python
python爬虫超时的处理的实例
2018/12/19 Python
基于python3实现倒叙字符串
2020/02/18 Python
Python爬虫实例——scrapy框架爬取拉勾网招聘信息
2020/07/14 Python
利用HTML5+CSS3实现3D转换效果实例详解
2017/05/02 HTML / CSS
html5指南-5.使用web storage存储键值对的数据
2013/01/07 HTML / CSS
赫里福德的一家乡村零售商店:Philip Morris & Son
2017/06/25 全球购物
个人自我鉴定怎么写
2013/10/28 职场文书
优秀毕业生推荐信
2013/11/02 职场文书
《跨越百年的美丽》教学反思
2014/02/11 职场文书
心理健康课教学反思
2014/02/13 职场文书
群众路线教育实践活动思想汇报(2014特荐篇)
2014/09/16 职场文书
2015秋季新学期开学寄语
2015/05/28 职场文书
使用Redis实现秒杀功能的简单方法
2021/05/08 Redis