生产环境下的pm2部署
标签(空格分隔): EBOOKCHAIN PM2 NODEJS
前言
部署前请先安装Ebookcoin
请参考官方wiki:https://github.com/Ebookcoin/ebookcoin/wiki/
pm2简介
Node.js默认单进程运行,对于32位系统最高可以使用512MB内存,对于64位最高可以使用1GB内存。对于多核CPU的计算机来说,这样做效率很低,因为只有一个核在运行,其他核都在闲置,pm2利用的node原生的cluster模块可以顺利解决该问题。
在线上服务器部署nodejs项目并且管理node服务会遇到诸多问题,在服务器上开启了node进程以后,我们很难统一管理进程,也不能查看详细信息和日志,如果一个接口报错了,我们需要进到服务器中,关闭进程,重启服务,然后查看命令行打印出的日志判断到底是什么问题,这明显加大了调试的难度。
pm2可以使node服务在后台运行(类似于linux的nohup),另外它可以在服务因异常或其他原因被杀掉后进行自动重启。由于Node的单线程特征,自动重启能很大程度上的提高它的健壮性。并且它是一个带有负载均衡功能的Node应用的进程管理器。当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载,PM2是完美的。它非常适合IaaS结构,但不要把它用于PaaS方案(随后将开发Paas的解决方案)。
更多信息请查看:
pm2 官网:http://pm2.keymetrics.io/
pm2 github:https://github.com/Unitech/pm2
pm2主要特性
- 原生的集群化支持(使用Node cluster集群模块)
- 记录应用重启的次数和时间
- 后台daemon模式运行
- 0秒停机重载,非常适合程序升级
- 停止不稳定的进程(避免无限循环)
- 控制台监控
- 实时集中log处理
- 强健的API,包含远程控制和实时的接口API ( Nodejs 模块,允许和PM2进程管理器交互 )
- 退出时自动杀死进程
- 内置支持开机启动(支持众多linux发行版和macos)
更多特性请查看:pm2的官网:http://pm2.keymetrics.io/
pm2与forever对比
到目前为止,我们仍然依赖漂亮俏皮的node-forever模块.它是非常伟大的模块,不过依然缺失一些功能:
- 有限的监控和日志功能
- 进程管理配置的支持差
- 未内置支持cluster以及优雅重启
- 代码库老化(意味着在升级node.js时频繁的失败)
- 未内置支持开机启动
- 重启可能失败
pm2安装和升级
$ npm install -g pm2
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 startup # 产生init 脚本保持进程活着
$ pm2 web # 运行健壮的 computer API endpoint (http://localhost:9615)
$ 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自身,会释放端口
$ pm2 updatePM2 # 更新内存里的pm2
运行进程的不同方式:
$ 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以fork模式运行bash shell脚本
$ pm2 start my-python-script.py -x --interpreter python #pm2以fork模式运行python脚本
硬重启:
$ pm2 dump
$ pm2 resurrect
pm2高级用法(远程部署)
生成远程部署所需的json文件,在应用程序目录下生成ecosystem.json
$ pm2 ecosystem
编辑修改ecosystem.json文件
{
"apps" : [{
"name" : "ebook", //项目的名字
"script" : "app.js", //项目主入口(Node.js)
"env": {
"COMMON_VARIABLE": "true"
},
"env_production" : {
"NODE_ENV": "production"
}
}],
deploy : {
production : {
user : "root", // 登陆用户名
host : "192.168.1.100", // 要部署的目标服务器IP地址或域名
ref : "origin/master", // 用于部署的Git仓库分支
repo : "https://github.com/Ebookcoin/ebookcoin.git", // Git仓库位置
path : "/var/www/production", // 部署目标服务器文件系统位置
"post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env production" // 部署后执行的命令,本案例:先安装依赖再启动
},
}
执行部署(自动发布网站项目)
$ pm2 deploy ecosystem.json production
更新部署
$ pm2 deploy production update
pm2启动模式分类
fork模式
pm2默认用fork模式启动,该模式有如下特性。
- 可以修改exec_interpreter,比如你的代码不是纯js,而是类似coffee script或者是其它语言如python/php
- 适合做本地开发测试用,只使用一个cpu
cluster模式
- 不可以修改exec_interpreter,只适合node开发的纯js程序
- 适合生产坏境部署用,尽可能多地使用cpu/内存等系统资源
- 用cluster来做负载均衡,业务代码零改动
pm2部署ebookcoin案例
本案例演示了如何利用pm2进行ebook blockchain的基本管理工作。
用pm2启动ebookcoin的app.js并将应用名字设置为“ebook”
clark@E540:/data/blockchain/ebookcoin$ pm2 start app.js --name ebook
[PM2] Spawning PM2 daemon with pm2_home=/home/clark/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /data/blockchain/ebookcoin/app.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ ebook │ 0 │ fork │ 20130 │ online │ 0 │ 0s │ 49% │ 13.2 MB │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
检查日志
该日志包含pm2自身、应用程序的日志(支持实时刷新,类似linxu的tail -f模式)
clark@E540:/data/blockchain/ebookcoin$ pm2 logs
[TAILING] Tailing last 10 lines for [all] processes (change the value with --lines option)
/home/clark/.pm2/pm2.log last 10 lines:
PM2 | 2016-09-26 15:00:25: PM2 PID file : /home/clark/.pm2/pm2.pid
PM2 | 2016-09-26 15:00:25: RPC socket file : /home/clark/.pm2/rpc.sock
PM2 | 2016-09-26 15:00:25: BUS socket file : /home/clark/.pm2/pub.sock
PM2 | 2016-09-26 15:00:25: Application log path : /home/clark/.pm2/logs
PM2 | 2016-09-26 15:00:25: Process dump file : /home/clark/.pm2/dump.pm2
PM2 | 2016-09-26 15:00:25: Concurrent actions : 1
PM2 | 2016-09-26 15:00:25: SIGTERM timeout : 1600
PM2 | 2016-09-26 15:00:25: ===============================================================================
PM2 | 2016-09-26 15:00:25: Starting execution sequence in -fork mode- for app name:ebook id:0
PM2 | 2016-09-26 15:00:25: App name:ebook id:0 online
/home/clark/.pm2/logs/ebook-error-0.log last 10 lines:
/home/clark/.pm2/logs/ebook-out-0.log last 10 lines:
0|ebook | info 2016-09-26 15:00:26 Forging enabled on account: 18314120909703123221L
0|ebook | info 2016-09-26 15:00:26 Forging enabled on account: 13969847998693785080L
0|ebook | info 2016-09-26 15:00:26 Forging enabled on account: 15336887350336188475L
0|ebook | info 2016-09-26 15:00:26 Forging enabled on account: 15106553597056061290L
0|ebook | info 2016-09-26 15:00:26 Forging enabled on account: 13719766223485644534L
pm2重启应用
clark@E540:/data/blockchain/ebookcoin$ pm2 restart ebook
[PM2] Applying action restartProcessId on app [ebook](ids: 0)
[PM2] [ebook](0) ?
┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ ebook │ 0 │ fork │ 28059 │ online │ 1 │ 0s │ 0% │ 10.5 MB │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
pm2重载应用
clark@E540:/data/blockchain/ebookcoin$ pm2 reload ebook
[PM2] Applying action reloadProcessId on app [ebook](ids: 0)
[PM2] [ebook](0) ?
┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ ebook │ 0 │ fork │ 28128 │ online │ 2 │ 0s │ 0% │ 10.5 MB │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
pm2查看已启动的应用列表
clark@E540:/data/blockchain/ebookcoin$ pm2 list
┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ ebook │ 0 │ fork │ 28128 │ online │ 2 │ 41s │ 0% │ 86.6 MB │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
pm2查看应用详情
clark@E540:/data/blockchain/ebookcoin$ pm2 show ebook
Describing process with id 0 - name ebook
┌───────────────────┬─────────────────────────────────────────┐
│ status │ online │
│ name │ ebook │
│ restarts │ 2 │
│ uptime │ 59s │
│ script path │ /data/blockchain/ebookcoin/app.js │
│ script args │ N/A │
│ error log path │ /home/clark/.pm2/logs/ebook-error-0.log │
│ out log path │ /home/clark/.pm2/logs/ebook-out-0.log │
│ pid path │ /home/clark/.pm2/pids/ebook-0.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 0 │
│ exec cwd │ /data/blockchain/ebookcoin │
│ exec mode │ fork_mode │
│ node.js version │ 0.12.15 │
│ watch & reload │ ? │
│ unstable restarts │ 0 │
│ created at │ 2016-09-26T09:05:29.979Z │
└───────────────────┴─────────────────────────────────────────┘
Revision control metadata
┌──────────────────┬─────────────────────────────────────────────┐
│ revision control │ git │
│ remote url │ https://github.com/Ebookcoin/ebookcoin.git │
│ repository root │ /data/blockchain/ebookcoin │
│ last update │ 2016-09-26T09:06:26.562Z │
│ revision │ f708fa4f523ec954b1a73694dec51ece7bb744c4 │
│ comment │ Merge pull request #4 from robbinhan/master │
│ branch │ master │
└──────────────────┴─────────────────────────────────────────────┘
Code metrics value
┌────────────┬────────┐
│ Loop delay │ 0.12ms │
└────────────┴────────┘
Add your own code metrics: http://bit.ly/code-metrics
Use `pm2 logs ebook [--lines 1000]` to display logs
Use `pm2 monit` to monitor CPU and Memory usage ebook
pm2停止应用
clark@E540:/data/blockchain/ebookcoin$ pm2 stop ebook
[PM2] Applying action stopProcessId on app [ebook](ids: 0)
[PM2] [ebook](0) ?
┌──────────┬────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────────┤
│ ebook │ 0 │ fork │ 0 │ stopped │ 2 │ 0 │ 0% │ 0 B │ disabled │
└──────────┴────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
将应用从pm2中删除
clark@E540:/data/blockchain/ebookcoin$ pm2 delete ebook
[PM2] Applying action deleteProcessId on app [ebook](ids: 0)
[PM2] [ebook](0) ?
┌──────────┬────┬──────┬─────┬────────┬─────────┬────────┬─────┬─────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
└──────────┴────┴──────┴─────┴────────┴─────────┴────────┴─────┴─────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
退出pm2
clark@E540:/data/blockchain/ebookcoin$ pm2 kill
[PM2] Stopping PM2...
[PM2][WARN] No process found
[PM2] All processes have been stopped and deleted
[PM2] PM2 stopped