使用pm2部署node生产环境的方法步骤


Posted in Javascript onMarch 09, 2019

一、PM2是什么

  • 是可以用于生产环境的Nodejs的进程管理工具,并且它内置一个负载均衡。它不仅可以保证服务不会中断一直在线,并且提供0秒reload功能,还有其他一系列进程管理、监控功能。并且使用起来非常简单。
  • 嗯嗯,最好的用处就是监控我们的生产环境下的node程序运行状态,让它给我们日以继日的处于工作状态。
  • pm2官方文档

二、为森么要使用pm2

  • 原始社会的我们开发node服务端程序一般过程:
    • 编写好node程序app.js,运行node app.js;或者写入script使用npm运行;打开浏览器访问;
    • 好像需要修改内容,浏览器对修改的内容没有显示出来?->node app.js->再次运行;
    • 浏览器忽然访问不到服务,好像出错啦?重启下->node app.js->再次运行;
    • 哎呀开了好多控制台窗口,一不小心关闭了,服务又访问不到了,继续打开控制台->node app.js->再次运行;
  • 好崩溃!好像有个工具nodemon;安装使用nodemon app.js;哇,可以自动监听文件修改变化自动重启,但是关闭控制台服务还是会被摧毁。
  • 通过这个很常用的场景,我们了解到要避免这些麻烦一个服务器至少需要有:后台运行和自动重启,这两个能力。
  • 再来看看使用pm2可拥有的能力:
    • 日志管理;两种日志,pm2系统日志与管理的进程日志,默认会把进程的控制台输出记录到日志中;
    • 负载均衡:PM2可以通过创建共享同一服务器端口的多个子进程来扩展您的应用程序。这样做还允许以零秒停机时间重新启动应用程序。
    • 终端监控:可以在终端中监控应用程序并检查应用程序运行状况(CPU使用率,使用的内存,请求/分钟等)。
    • SSH部署:自动部署,避免逐个在所有服务器中进行ssh。
    • 静态服务:支持静态服务器功能
    • 支持开发调试模式,非后台运行,pm2-dev start <appName>;
    • 。。。。。太过强大!

pm2常用命令

启动服务pm2 start <script_file|config_file> [options] 启动指定应用

pm2 start app.js        //启动app.js应用
pm2 start app.js --name app  //启动应用并设置name
pm2 start app.sh        //脚本启动

pm2 start app.js --watch  //监听模式启动,当文件发生变化,自动重启

//max 表示PM2将自动检测可用CPU的数量并运行尽可能多的进程
//max可以自定义,如果是4核CPU,设置为2则占用2个
pm2 start app.js -i max //启用群集模式(自动负载均衡)

pm2-dev start ... // 开发模式启动,即不启用后台运行

查看启动列表pm2 list

显示应用程序详细信息pm2 show <appName> [options] 显示指定应用详情

pm2 show [Name]   //根据name查看
pm2 show [ID]    //根据id查看

停止指定应用pm2 stop <appName> [options] 停止指定应用

pm2 stop all        //停止所有应用
pm2 stop [AppName]    //根据应用名停止指定应用
pm2 stop [ID]       //根据应用id停止指定应用

重启应用pm2 reload|restart <appName> [options] 重启指定应用

pm2 restart app.js    //同时杀死并重启所有进程,短时间内服务不可用,生成环境慎用
pm2 reload app.js    //重新启动所有进程,0秒重启,始终保持至少一个进程在运行
pm2 gracefulReload all  //以群集模式重新加载所有应用程序

启动静态服务器pm2 serve ./dist 8080将目录dist作为静态服务器根目录,端口为8080

删除应用pm2 delete <appName> [options] 删除指定应用;如果修改了应用配置行为,需要先删除应用,重新启动后方才会生效,如修改脚本入口文件;

pm2 delete all        //关闭并删除应用
pm2 delete [AppName]    //根据应用名关闭并删除应用
pm2 delete [ID]      //根据应用ID关闭并删除应用

pm2 kill 杀掉pm2管理的所有进程;

pm2 logs <appName> 查看指定应用的日志,即标准输出和标准错误

pm2 logs      //查看所有应用日志
pm2 logs [Name]  //根据指定应用名查看应用日志
pm2 logs [ID]   //根据指定应用ID查看应用日志

pm2 monit 监控各个应用进程cpu和memory使用情况;

PM2配置方式

命令生产默认示例配置文件pm2 ecosystem或pm2 init,运行默认会生成ecosystem.config.js配置文件

module.exports = {
 apps: [
  {
   name: 'back-Api',   //应用名
   script: './server/start.js',  //应用文件位置
   env: {
    PM2_SERVE_PATH: "./apidoc",  //静态服务路径
    PM2_SERVE_PORT: 8080,  //静态服务器访问端口
    NODE_ENV: 'development' //启动默认模式
   },
   env_production : {
    NODE_ENV: 'production' //使用production模式 pm2 start ecosystem.config.js --env production
   },
   instances:"max",     //将应用程序分布在所有CPU核心上,可以是整数或负数
   instance_var: "INSTANCE_ID",
   exec_mode: "cluster",
   watch:[
    "server",
   ], //监听模式,不能单纯的设置为true,易导致无限重启,因为日志文件在变化,需要排除对其的监听
   merge_logs: true,     //集群情况下,可以合并日志
  }
 ],
 deploy: {
   production : {
    user: 'node',           //ssh 用户
    host: '212.83.163.1',       //ssh 地址
    ref: 'origin/master',       //GIT远程/分支
    repo: 'git@github.com:repo.git',  //git地址
    path: '/var/www/production',    //服务器文件路径
    "post-deploy": 'npm install && pm2 reload ecosystem.config.js --env production' //部署后的动作
   }
 }
};

自定义json配置文件如:processes.json;启动pm2 start processes.json

{
   "apps": [{
    "name": "app", //名称
    "script": "./", //程序入口
    "cwd": "./",      //根目录
    "watch":[
      "views"
    ],//需要监控的目录
    "error_file":"./logs/err.log",//错误输出日志
    "out_file":"./logs/out.log", //日志
    "log_date_format":"YYYY-MM-DD HH:mm Z" //日期格式
    }]
  }

pm2常用配置项解析

1. apps:json结构,apps是一个数组,每一个数组成员就是对应一个pm2中运行的应用

2. name:应用程序名称"app"

3. cwd:应用程序所在的目录"./"

4. script:应用程序的脚本路径"./"

5. log_date_format: 日志文件名输出日期格式"YYYY-MM-DD HH:mm Z"

6. error_file:自定义应用程序的错误日志文件"./logs/app-err.log",

7. out_file:自定义应用程序日志文件"./logs/app-out.log"

8. instances: 应用启动实例个数,仅在cluster模式有效 默认为fork;或者 max

9. min_uptime:最小运行时间,这里设置的是60s即如果应用程序在60s内退出,pm2会认为程序异常退出,此时触发重启max_restarts设置数量

10. max_restarts:设置应用程序异常退出重启的次数,默认15次(从0开始计数)

11. cron_restart:定时启动,解决重启能解决的问题

12. watch:是否启用监控模式,默认是false。如果设置成true,当应用程序变动时,pm2会自动重载。这里也可以设置你要监控的文件。

13. "ignore_watch": [                           // 不用监听的文件
            "node_modules",
            "logs"
        ],
13. merge_logs:// 设置追加日志而不是新建日志

14. exec_interpreter:应用程序的脚本类型,这里使用的shell,默认是nodejs

15. exec_mode:应用程序启动模式,这里设置的是cluster_mode(集群),默认是fork

16. autorestart:启用/禁用应用程序崩溃或退出时自动重启,默认为true, 发生异常的情况下自动重启

17. vizion:启用/禁用vizion特性(版本控制)

18. "args": "", // 传递给脚本的参数

19. env: {
        PM2_SERVE_PATH: "./apidoc",    //静态服务路径
        PM2_SERVE_PORT: 8080,   //静态服务器访问端口
        NODE_ENV: 'development' //启动默认模式
      },

20. env_production : {
        NODE_ENV: 'production'  //使用production模式 pm2 start ecosystem.config.js --env production
      },

pm2配合log4js处理日志

1、pm2启动时通常会发现log4js记录不到日志信息;

2、解决方案,安装pm2的pm2-intercom进程间通信模块

3、在log4js的配置文件logger.js里添加如下命令:

pm2: true, 
pm2InstanceVar: 'INSTANCE_ID'

4、pm2配置文件中添加"instance_var": "INSTANCE_ID", // 添加这一行 字段

5、发现如果没有设置群集模式"exec_mode": "cluster",也会记录不到;

其他

log4js日志配置使用详情Koa日志中间件封装开发(log4js)

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

Javascript 相关文章推荐
javascript void(0)的妙用
Oct 21 Javascript
一个简单的瀑布流效果(主体形式自写)
May 27 Javascript
JS判断字符串包含的方法
May 05 Javascript
全面了解JS中的匿名函数
Jun 29 Javascript
JavaScipt选取文档元素的方法(推荐)
Aug 05 Javascript
在JavaScript中调用Java类和接口的方法
Sep 07 Javascript
javascript 利用arguments实现可变长参数
Nov 21 Javascript
vue-router判断页面未登录自动跳转到登录页的方法示例
Nov 04 Javascript
微信小程序实现录音时的麦克风动画效果实例
May 18 Javascript
微信小程序在线客服自动回复功能(基于node)
Jul 03 Javascript
基于Node的Axure文件在线预览的实现代码
Aug 28 Javascript
vue中echarts的用法及与elementui-select的协同绑定操作
Nov 17 Vue.js
Koa日志中间件封装开发详解
Mar 09 #Javascript
详解vue2.6插槽更新v-slot用法总结
Mar 09 #Javascript
Node.js Stream ondata触发时机与顺序的探索
Mar 08 #Javascript
详解JSON和JSONP劫持以及解决方法
Mar 08 #Javascript
Node.js Event Loop各阶段讲解
Mar 08 #Javascript
vue基础之data存储数据及v-for循环用法示例
Mar 08 #Javascript
vue.js使用v-model实现表单元素(input) 双向数据绑定功能示例
Mar 08 #Javascript
You might like
PHP小教程之实现链表
2014/06/09 PHP
thinkphp3.x连接mysql数据库的方法(具体操作步骤)
2016/05/19 PHP
PHP函数按引用传递参数及函数可选参数用法示例
2018/06/04 PHP
Laravel源码解析之路由的使用和示例详解
2018/09/27 PHP
php5对象复制、clone、浅复制与深复制实例详解
2019/08/14 PHP
alixixi runcode.asp的代码不错的应用
2007/08/08 Javascript
event.X和event.clientX的区别分析
2011/10/06 Javascript
Javascript中使用parseInt函数需要注意的问题
2015/04/02 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
2015/05/09 Javascript
JavaScript保存并运算页面中数字类型变量的写法
2015/07/06 Javascript
深入浅析jQuery对象$.html
2016/08/22 Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
2016/08/25 Javascript
jQuery为DOM动态追加事件的方法
2017/02/16 Javascript
vue-resource调用promise取数据方式详解
2017/07/21 Javascript
JS实现的找零张数最小问题示例
2017/11/28 Javascript
nuxt框架中对vuex进行模块化设置的实现方法
2019/09/06 Javascript
Layui Form 自定义验证的实例代码
2019/09/14 Javascript
JavaScript鼠标悬停事件用法解析
2020/05/15 Javascript
Vue+axios封装请求实现前后端分离
2020/10/23 Javascript
Python中zip()函数用法实例教程
2014/07/31 Python
Python中模块与包有相同名字的处理方法
2017/05/05 Python
Python实现登录接口的示例代码
2017/07/21 Python
Python探索之SocketServer详解
2017/10/28 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
Python简单实现socket信息发送与监听功能示例
2018/01/03 Python
用Django实现一个可运行的区块链应用
2018/03/08 Python
Django forms组件的使用教程
2018/10/08 Python
pandas的to_datetime时间转换使用及学习心得
2019/08/11 Python
Pyinstaller 打包发布经验总结
2020/06/02 Python
Canvas波浪花环的示例代码
2020/08/21 HTML / CSS
毕业设计论文致谢词
2015/05/14 职场文书
亮剑观后感300字
2015/06/05 职场文书
离婚民事起诉状
2015/08/03 职场文书
小学生法制教育心得体会
2016/01/14 职场文书
Javascript中async与await的捕捉错误详解
2022/03/03 Javascript
处理canvas绘制图片模糊问题
2022/05/11 Javascript