聊聊如何利用pm2部署和管理node应用

为什么要写这篇文章

最近利用ant-design-pro结合koa2搭建了一套后台管理系统,用于管理个人项目。由于需要将koa2代码部署到服务器上,很自然地就想到了用pm2来发布和管理。其实自己之前是有在工作中使用pm2的,但是我都是在别人搭建好的环境下进行使用,没有很好地领会精髓。在这次部署个人项目的实践中,自己从头到尾把控整个部署流程,所以收获是有很多的,因此才会准备写这篇文章,将自己的所学所知整理成文,既方便自己以后进行回顾,也可以帮助想要了解这块知识的朋友。

初识pm2

首先,我们要知道pm2是什么。pm2是一个node应用的监控管理工具,具有如下的功能:

  1. 以守护进程的方式将我们的node应用运行在后台
  2. 提供简便的方式启动或停止node应用
  3. 监控node应用的运行状态,并提供当node应用崩溃时自动重启的功能(不用手动node app.js啦)
  4. 开启cluster模式后,会采用负载均衡的策略将node应用跑在多个cpu上,从而充分发挥多核cpu的性能
  5. 配合ecosystem.config.js,可以方便地进行一键部署

pm2常用的命令如下:

# Fork mode
pm2 start app.js --name my-app #启动一个node应用,并将其命名为my-app

# Cluster mode
pm2 start app.js -i 0        # 启动一个node应用,并开启cluster模式,使用的cpu数量取决于主机cpu的可用核数
pm2 start app.js -i max      # 跟上述命令效果一致,不推荐使用

# Listing
pm2 list               # 以表格的形式列出当前所有node应用的信息
pm2 jlist              # 以原生JSON的形式列出当前所有node应用的信息
pm2 prettylist         # 以美化过的JSON形式列出当前所有node应用的信息
pm2 describe 0         # 列举出id为0的应用的所有信息

# Logs
pm2 logs [--raw]       # 以流的形式列举出所有node应用的日志
pm2 flush              # 清空所有日志文件
pm2 reloadLogs         # 重载所有日志文件

# Actions
pm2 stop all           # 停止所有node应用
pm2 restart all        # 重启所有node应用
pm2 reload all         # 重载所有node应用,与restart不同的是这种方式可以实现不停机更新的效果
pm2 stop 0             # 停止id为0的node应用
pm2 restart 0          # 重启id为0的node应用
pm2 delete 0           # 删除id为0的node应用,pm2 list上就不会再出现了
pm2 delete all         # 删除所有node应用
复制代码

使用pm2部署node应用

除了上述直接在命令行中操作pm2,更常见的使用方式是使用约定的配置文件(ecosystem.config.js)来管理。通过这个文件,我们可以简单高效的管理和发布多个node应用,下面将列出常见的配置:

module.exports = {
  //apps是个数组,里面可以存放多个node应用实例的配置
  apps : [{
    name: 'my-app1',           //指定node应用的名称
    script: './src/index1.js', //指定node应用的入口文件
    exec_mode: 'cluster',      //开启cluster集群模式
    instances: '0',            //根据cpu可用核数运行最大数量的node应用实例
    watch:true,                //开启监听模式,任意文件内容发生改变,都会重启node应用
    ignore_watch: [],	       //监听模式下,忽略的文件列表
    env: {                     //默认的环境变量
      NODE_ENV: "production",
      MODE: "default"
    },
    env_production: {          //生产环境变量,需要在命令行中添加参数 --env production
      NODE_ENV: "production",
      MODE: "pro"
    },
    env_pre_production: {         //预生产环境变量,需要在命令行中添加参数 --env pre_production
      NODE_ENV: "pre_production",
      MODE: "pre"
    }
  },{
    name: 'my-app2',
    script: './src/index2.js',
    exec_mode: 'fork',         //默认的模式,只会在单核上运行node应用,无法充分利用多核cpu的性能,一般不推荐使用
    env: {                     
      NODE_ENV: "production",
      MODE: "default"
    },
    env_production: {
      NODE_ENV: "production",
      MODE: "pro"
    },
    env_pre_production: {
      NODE_ENV: "pre_production",
      MODE: "pre"
    }
  }],
  //部署相关的配置
  deploy : {
    //生产环境的部署,部署的方式以deploy的key作为区分
    production : {
      user : 'root', //服务器用户名                                                             
      host : '8.8.8.8', //服务器ip地址
      ref  : 'origin/main', //需要拉取的仓库分支
      repo : 'git@github.com:test/test.git', //仓库地址
      path : '/var/test', //需要发布到服务器的路径
      'pre-setup': '', //在安装进程启动之前需要执行的命令
      'post-setup': "npm install && pm2 start ecosystem.config.js --env production", //拉取代码之后需要执行的指令
      'pre-deploy': '', //部署之前的钩子,暂不清楚与'post-deploy'的区别,共同点是都可以进行reload的操作
      'post-deploy': 'pm2 reload ecosystem.config.js --env production'
    },
    //预生产环境的部署,部署的方式以deploy的key作为区分
    pre_production : {
      user : 'root',
      host : '8.8.8.8',
      ref  : 'origin/main',
      repo : 'git@github.com:test/test.git',
      path : '/var/test',
      'pre-setup': '',
      'post-setup': "npm install && pm2 start ecosystem.config.js --env pre_production",
      'pre-deploy': '',
      'post-deploy': 'pm2 reload ecosystem.config.js --env pre_production'
    }
  }
}
复制代码

使用pm2部署的完整指令是pm2 deploy <configuration_file> <environment> <command>,默认的<configuration_file>就是ecosystem.config.js,所以可以省略该参数。就是deploy里面的key,可以区分不同的发布环境,指定需要执行的指令。
例如要发布到预生产环境上,执行的指令是pm2 deploy pre_production。这里需要注意的是,如果是第一次发布,需要执行pm2 deploy pre_production setup,从而走pre-setuppost-setup钩子,执行我们设置的初始化安装命令。还有一点需要注意的是由于存在拉仓库代码的行为,所以我们需要为服务器配置ssh免密登录,这样才能保证成功地拉下代码。
在发布完成后,我们可以登录到服务器上,输入pm2 list,查看node应用的运行状态,如果是online,那么恭喜你,已经部署成功啦!

结语

ci/cd这一套流程其实会涉及很多知识,虽然在实践的过程中,会遇到很多问题,但是只有通过不断的实践,才能真正领悟其中的精髓。未来我还会尝试更多的ci/cd工具,同时也会把自己学到的经验整理成文分享出来,帮助需要的人。

个人博客

www.carlblog.site
最近自己搭建了个人博客,上面会定期发布关于技术经验总结的文章,希望感兴趣的小伙伴都去踩踩,不要跑堂啊!~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享