6.5.2 生产环境下的pm2部署

优质
小牛编辑
127浏览
2023-12-01

标签(空格分隔): EBOOKCHAIN PM2 NODEJS


[TOC]

前言

部署前请先安装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