当前位置:首页 > 经验 >

pm2命令(pm2安装教程)

来源:原点资讯(www.yd166.com)时间:2024-03-27 17:23:52作者:YD166手机阅读>>

前言

好不容易写了一个nodejs应用,不知道该怎么部署才好:

js复制代码

const app = express(); ... app.listen(3000, '0.0.0.0, () => { console.log("server started at 0.0.0.0:3000") });

直接一把node server.js部署之后,当服务挂了,却根本不知道原因,可能这个时候想起来是不是该给我们的应用加一个日志,是不是应该给我们展示一下node应用的状态,是不是应该做一个负载均衡等等,我们写业务都忙不过来哪里有时间去写这么多东西啊!但是不写的话如果出现各种问题那就只能歇菜了,没办法就只能加班了啊!

幸好有pm2,它是nodejs进程管理工具,目前如果说它排第二没人敢排第一;它正好帮助我们做了这些功能,我们可以早点下班了!下面我们会从这些方面来学习pm2:

pm2常用功能 实战用pm2部署next应用 pm2线上故障排查 pm2原理

pm2常用功能

首先我们新建一个service.js来练习一下pm2常用功能,server.js代码如下:

js复制代码const http = require('node:http'); // Server has a 5 seconds keep-alive timeout by default http .createServer((req, res) => { res.write('hello\n'); res.end(); }) .listen(3000); console.log("http server started at 3000......")

  • pm2 start [options] [name|namespace|file|ecosystem|id...]
  • 启动pm2进程管理,注意第一次启动pm2进程管理必须使用这个命令,options可以是一个file,或者我们的应用id,或者配置文件(这个后面再讲),我们可以运行一下pm2 start server.js这样一个node服务就在3000端口跑起来了;那么怎么看它是否运行起来了呢?
  • pm2 restart 重启应用,第一次启动应用必须使用pm2 start
  • pm2 reload 重新加载程序;与restart不同,restart会*死进程并重启,而reload实现了0秒停机时间重新加载;但是需要注意的是该方式可能会报错,例如在部署next应用时如果使用reload则会报端口号被占用的错误,所以reload之前经常需要先停机(pm2 stop),但是这样的话和restart一样了,pm2 stop pm2 reload = pm2 restart
  • pm2 ls
  • 查看当前pm2进程列表,如图1可以看到我们刚才的服务status是online说明一直在运行;我们在js文件中打印了一些文字,这个又在哪里查看呢?

图1

  • pm2 logs
  • 查看pm2日志,此时我们可以观察看日志默认存放位置是~/.pm2/logs/service-out[error].log,其中sevice就是我们的appName,后面当日志比较多的时候我们可以直接翻这个文件来查看日志,划重点了,这个地址在我们后面会经常用到,一定要在脑子里面给它记住!
  • 拿到了日志文件,下面就是一顿操作猛如虎了。我们做前端的同学可能对于linux操作并不熟悉,一上手就用cat或者vi查看日志,但是日志太多眼都瞎了根本看不过来;有没有一种动态滚动查看日志的方法?是有的,用less命令;如图2就是我们的日志;

图2

  • pm2 monit 这个命令是一个神器,它提供了可视化界面实时监控线上应用,可以看到所有实例的所有日志;在线上排查问题的时候非常实用,使用该命令查看的结果如图3:

图3

  • pm2 flush 当日志文件比较多之后会占用大量的磁盘空间,需要主动清除
实战-用pm2部署next应用

next是一个react服务端渲染框架,与vue的nuxt和angular的nest齐名,我们先初始化一个项目npx create-next-app@latest

然后运行npm run dev就可以将项目运行起来,然后我们运行npm run build,得到打包文件再运行npm run start,可以在3000端口访问到该应用,接下来我们用pm2部署该应用;由于next的部署是通过npm命令而不是一个js文件来执行的所以我们需要这样来执行pm2 start "npm run start",项目就跑起来了,如图4

pm2命令,pm2安装教程(1)

图4

但是问题并没有这么简单,我们有测试环境也有生产环境,都需要部署,这个时候我们还用原来的命令来部署,就无法区分环境了

如果测试环境和生产环境端口号不一样怎么办?

第一次启动应用使用pm2 start,第二次需要使用pm2 restart,这好像也不好办?

别急我们接着讲;如果我们需要区分环境了,那么单单使用命令已经不能够满足我们的需要了,我们可以创建一个配置文件ecosystem.config.js来配置不同的环境,它的配置如下:

pm2命令,pm2安装教程(2)

pm2命令,pm2安装教程(3)

我们先为我们的项目创建一个配置文件:

js复制代码module.exports = { apps : { name:'template', }, };

突然发现我们没有nodejs的脚本文件,我们只有一个"npm run start"命令,这时可以直接调用node-modules中的next脚本,配置如下:

js复制代码 module.exports = { apps : { name:'template', script:'./node_modules/.bin/next', args:'start' }, };

当我们的应用运行时间较长,为了防止内存泄漏,我们配置一个max_memory_restart:"1G",超过这个值之后应应用重启,这样不至于应用崩溃,接下来将自动重启设置为true:autorestart: true,我们如果说想要手动进行部署控制的话还需要把watch改为false,默认情况为true,也就是说有文件改变的时候应用会自动重启,有时候我们可能会远程传输一些文件到public文件夹但是这种情况并不需要重启应用

接下来我们解决第一个问题:有测试环境和生产环境或者还有预发环境,那么我们就在配置文件中配置一下env对象,一般需要配置端口号、环境变量、主机,默认为生产环境,其他的就用env_表示:

js复制代码 module.exports = { apps : { name:'template', script:'./node_modules/.bin/next', args:'start', max_memory_restart:'1G', autorestart: true, watch: false, env_test: { ENV: 'test', PORT: 8000, HOST: '0.0.0.0', }, env: { ENV: 'prod', PORT: 8001, HOST: '0.0.0.0', }, }, };

这样配置之后我们执行pm2 start ecosystem.config.js,默认是使用的env配置,所以我们可以在8001端口访问到node应用;如果需要部署测试环境那么需要加一个env参数:pm2 start ecosystem.config.js --env test,一顿操作之后8001无法访问了,8000可以访问了,测试环境部署成功!这样我们的pm2应用就部署成功了!部署成功之后难免有时候会出现问题,或者某些接口报错了,这个时候我们需要进行故障排查

pm2线上故障排查

可以用更加复杂的案例来进行练习,但是我们这里先使用较为简单的案例进行讲解,因为故障排查的一般步骤都是差不多的;我们先运行我们当前的应用pm2 start ecosystem.config.js --env test,可以看到运行之后状态为online,别急可以等一等再查看一下状态pm2 ls,如果这个时候还是online,那么应用启动成功了一半。为什么这么说呢?我们来看一看产生故障时的两种情况:

  1. 重启了应用发现应用跑不起来了,首先我们应该想到的就是日志:pm2 logs appName:最后发现日志很多那么直接使用less查看日志,然后command G跳转到日志最后一行往上稍微翻一翻就可以看到报错,然后修复就行了
  2. 应用启动成功了,但是页面显示502,这说明应用可能一直在重复地重启,既然应用状态是online那么就可以使用可视化页面监控当前pm2进程:pm2 monit,查看当前应用内存占用、CPU占用以及实时日志,可以定位到问题;这种方式也可以排查刚出现的线上问题;这种情况就是虚假的启动成功,需要仔细斟酌
pm2原理

要了解pm2原理首先需要了解一下nodejs的cluster模块

cluster模块

如果像我们文章开头那样直接node server.js部署nodejs应用,由于js是单线程的所以只能一个进程,只能在一个CPU中进行计算,无法应用服务器的多核CPU,所以需要通过多进程分发策略调度起所有的CPU;

nodejs的cluster模块是这样进行分发的:主进程和子进程分别监听不同端口,通过主进程将请求分发给子进程,从而实现负载均衡,那么cluster如何进行进程分发呢?让我们看看主进程是如何分发的(子进程仍然使用我们开篇写的service.js):

js复制代码const cluster = require('node:cluster') ; const { cpus } = require('node:os') ; const process = require('node:process'); const numCPUs = cpus().length; if (cluster.isPrimary) { console.log(`Primary ${process.pid} is running`); // Fork workers. for (let i = 0; i < numCPUs; i ) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { require('./service.js') console.log(`Worker ${process.pid} started`); }

可以看到判断只要是主进程那么直接调用fork,fork内部其实是启动了一个Worker继续调用当前这个js但是这个时候cluster.isPrimary为false,进入子进程判断,执行service.js,有了这个基础我们再来看pm2源码

pm2源码解析

首先我们需要寻找pm2项目的入口文件,先看一看它的package.json:

pm2命令,pm2安装教程(4)

首页 1234下一页

栏目热文

pm2.5空气质量(广州pm2.5空气质量)

pm2.5空气质量(广州pm2.5空气质量)

新京报快讯(记者 张璐)“双碳目标”最近成为公众热议的话题,它和大家关注的PM2.5有什么关系?在“北京国际大都市清洁空...

2024-03-27 17:53:59查看全文 >>

pm2.5浓度高(pm2.5值的范围)

pm2.5浓度高(pm2.5值的范围)

近年来,多项研究表明,空气污染尤其细微颗粒物(PM2.5)污染是心血管疾病的重要危险因素之一。9月22日,阜外医院李静等...

2024-03-27 17:58:19查看全文 >>

pm25是什么意思啊(pm2.5是什么意思如何减少)

pm25是什么意思啊(pm2.5是什么意思如何减少)

信息在通信系统中的表达方式是信号,也就是说信号上承载了相关的信息,移动通信系统利用信号的传播来传递信息。1.逻辑信号与物...

2024-03-27 17:36:05查看全文 >>

pm2.5查询(pm2.5在哪儿查询)

pm2.5查询(pm2.5在哪儿查询)

随着人们对环境保护意识的不断提高,空气质量成为了人们关注的焦点。为了方便地获取各地的空气质量数据,空气质量查询API应运...

2024-03-27 17:58:25查看全文 >>

pm2多少最好(pm2.5参考值多少最好)

pm2多少最好(pm2.5参考值多少最好)

有的人买空气净化器是为了除宠物绒毛、灰尘、花粉过敏源等大颗粒物;有人买空气净化器是为了除甲醛、甲苯等对人体有毒的气体;还...

2024-03-27 17:32:24查看全文 >>

typeerror对象不支持怎么解决(opentype属性不能用怎么解决)

typeerror对象不支持怎么解决(opentype属性不能用怎么解决)

本节是第五讲的第十三小节,上节为大家介绍了标准库一些常用模块,本节将为大家介绍Python语言的面向对象程序设计。面向对...

2024-03-27 17:41:49查看全文 >>

智能对象不能编辑怎么解决(智能对象使用方法和技巧)

智能对象不能编辑怎么解决(智能对象使用方法和技巧)

智能对象与普通图层的区别缩览图的不同我们在将图片转换成智能对象后,在给图片的缩小及放大后,对图片的清晰度是不会改变的,这...

2024-03-27 17:59:41查看全文 >>

对象不支持属性与方法(对象引用未设置为对象实例)

对象不支持属性与方法(对象引用未设置为对象实例)

1、问题描述在做vue 项目时,有时候需要给data中的对象(obj)添加新的属性(a),并用新的属性做页面显示或者v-...

2024-03-27 18:05:59查看全文 >>

对象不支持print属性或方法(为什么对象不支持print)

对象不支持print属性或方法(为什么对象不支持print)

golang反射理论基础反射就是动态的获取对象的信息,动态的执行对象的方法,为什么不直接获取对象的属性呢?为什么不直接调...

2024-03-27 17:29:10查看全文 >>

手机网页不能创建对象(无法创建对象问题怎么解决)

手机网页不能创建对象(无法创建对象问题怎么解决)

什么是TypeScript的对象?生活中,对象是一个具体的事物,比如:你的电脑、你的手机、古力娜扎、周杰伦(周董)等都是...

2024-03-27 18:03:32查看全文 >>

文档排行