此文本来是作为系列文章中的上一篇《Nodejs开发进阶G-部署和管理》的一个部分,但由于内容较多和篇幅限制,现在独立成篇。
nodejs的执行是非常简单的。但在真正的生产环境里面部署和运行,却需要考虑更多的其他的情况和因素。这时,就需要一些功能更加丰富,更加适应生产环境的管理工具。比如笔者经常使用的PM2(图)。
PM2 npm的官方网站在: pm2.io/
相关技术特性,功能和使用文档等细节信息,都可以在其官网查阅。
概述和特点
PM2的得名应该是Process Manager Version 2。虽然它能够提供非常丰富的功能和应用方式,但从笔者的应用经验和体验而言,主要有以下几点:
- 多应用管理
PM2可以在一个工具里面,管理很多nodejs应用程序。这些应用程序,可以是逻辑上有关联的,也可以是没有任何关系的独立nodejs应用。这样,就给大型应用系统的模块化规划和部署带来了很大的灵活性。做到了有点类似多个VM的应用效果。
例如,笔者参与开发的一个系统包括前端、API、支付接口、文件服务和数据服务等应用,在开发和测试的时候,它们都可以部署在一个测试开发主机上;而在生产环境中,它们可能是部署在不同的服务器上面的,也可能是混合部署,这时使用PM2进行管理,就比较方便。
- 应用守护
对于单个的Nodejs应用,在生产环境中的运行是需要可用性的要求的。在这个方面,PM2可以提供应用程序的监控和自动重启的功能,可以保证应用在出现错误崩溃的时候,也可以重新启动来保证Web应用的服务始终可用,从而提供了一定的容错能力和更好的应用体验。这个功能很像一种看门狗程序。
- 应用生命周期管理
PM2提供了完整的应用程序运行的生命周期管理,包括应用程序的启动、关闭、服务化等等。
- 运行状态和日志
PM2可以快速的检查各个应用的运行情况、资源占用和日志信息。PM2的日志可以自动rotate,无需担心磁盘占用超载引起的系统故障。
- 群集管理
PM2可以利用nodejs的群集应用执行机制,将简单的Nodejs程序,转化为群集程序进行运行,当然,这时没有所谓的IPC和进程协调的问题,但这个方法完全不需要对原来的应用进行改造,简单方便,立即就可以利用到现代化多处理器平台的优势和特点。
比如很多后端Web API类型的应用,就比较适合使用这种方式。对于单个节点,本身就能够提供负载均衡的能力;对于多个节点,也可以配合负载均衡系统,来实现网络级别的负载均衡,从而在不同的层面上扩展应用的处理和服务能力。
这些内容,我们都会在后续的操作和使用环节中,有更加深入和直观的理解。
安装和使用
在nodejs中,PM2可以作为全局的npm进行安装:
sudo npm i pm2 -g
安装完成之后,就可以使用pm2命令和其相关的子命令,来进行nodejs应用程序的管理了。如我们第一次执行 pm2 list 命令,可能会看到下面的界面:
pm2
-------------
__/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____
_\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___
_\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__
_\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___
_\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____
_\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________
_\/\\\_____________\/\\\_____________\/\\\___/\\\/___________
_\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_
_\///______________\///______________\///__\///////////////__
Runtime Edition
PM2 is a Production Process Manager for Node.js applications
with a built-in Load Balancer.
Start and Daemonize any application:
$ pm2 start app.js
Load Balance 4 instances of api.js:
$ pm2 start api.js -i 4
Monitor in production:
$ pm2 monitor
Make pm2 auto-boot at server restart:
$ pm2 startup
To go further checkout:
http://pm2.io/
-------------
这里简单描述了pm2的特点和定位:
"PM2是一个为Node.js应用程序设计和生产环境设计的进程管理程序,内置负载均衡"。
同时简单例举了几个基本常用的pm2命令。
在正式开始之前,作为一个比较好的安全实践建议,我们一般使用普通用户的账号来运行pm2。这样,所有的pm2操作和应用程序的运行权限都被限制在这个账号中,如果出了问题,也不会对系统造成致命性的影响。
在生产和运维实践中,经常使用到的PM2功能和操作如下:
- 创建并启动nodejs应用程序
cd projectfolder
APPSEC=topsectret pm2 start . --name appname
这里可以在命令中设置一些启动时的环境参数。这里使用的"."是程序入口,当前文件夹中index.js文件的简写,如果不使用这个文件作为程序入口,应指定特定的js文件。
- 查看应用列表和状态
pm2 list
pm2 show 1
pm2 monit 2
命令执行的效果可能如上图所示。应用程序加入pm2列表之后,pm2会给每个应用程序都分配一个ID,如0,1等,会显示在list列表中。用户可以使用这个ID来标识应用,也可以使用设置的程序名称(--name 选项)。这个列表还可以显示这些应用程序的版本、运行模式、在线状态、CPU和内存用量,以及整体的资源、磁盘和网络使用等信息。
要查看特定应用的详细情况,可以使用show子命令;如果要监视特定应用程序,可以使用monit子命令。它可以提供一个类似仪表板的视图,可以更直观和方便的监控应用的运行,包括CPU、内存的用量,应用程序元数据和日志信息:
- 停止和重启应用
pm2 stop app
pm2 restart app
pm2 restart all
可以使用all来标识所有应用程序。这些命令支持同时操作多个应用程序。
- 查看应用日志
查看应用日志,可以使用log命令:
pm2 logs 1
pm2 flush
logs命令,可以查看指定应用的日志内容,默认情况下,它会展示对应应用程序的信息和错误日志文件的最新几行内容;flush命令,可以清空所有日志内容。
- 保存应用为服务
pm2启动后,就可以在后台运行,并维持应用系统的运行和状态。但这里有一个问题,如果没有特别的配置,如果此时系统由于故障或者操作重新启动,这些设置包括应用程序列表和状态就会丢失。当然pm2的设计考虑到了这一点,它可以通过设置将当前的pm2项目保存为系统服务,以备下次操作系统重新启动时自动加载,这部分内容,我们在后面的章节专门讨论。
- 从列表中删除
pm2 delete 2
将应用程序从PM2列表中删除。
应用持久化
如果想要将PM2和其应用程序列表,作为系统级的服务进行应用,需要一些额外的操作。
- 生成服务脚本
可以使用startup子命令,来生成一个服务命令脚本:
js
$ pm2 startup
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u yanjh --hp /home/yanjh
这个服务脚本,用于在操作系统中安装pm2软件服务程序。所以,脚本和命令的内容,是和目标系统使用的服务程序体系是相关的。比如systemd(主流的Linux)、systemv(版)、upstart(Ubuntu14)、lunchd(Mac OS)等等。默认情况下startup会自动检测当前系统服务体系,但如果有问题,可能需要手动指定所使用的服务系统。
- 执行服务脚本
这一步,需要使用系统管理员账号,来执行上一步骤生成的服务启动脚本。其实就是在系统中安装一个服务程序pm2,并且指定此服务是一个用户服务。
这个命令,会生成一个service脚本,并安装到系统中(这里以systemd为例):
js
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target
[Service]
Type=forking
User=yanjh
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/yanjh/.pm2
PIDFile=/home/yanjh/.pm2/pm2.pid
Restart=on-failure
ExecStart=/usr/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/lib/node_modules/pm2/bin/pm2 kill
[Install]
WantedBy=multi-user.target
Target path
/etc/systemd/system/pm2-yanjh.service
- 保存pm2状态
前面的两个步骤,其实只是将pm2安装成为一个系统服务,pm2是可以随系统服务启动而启动的,但当前的应用程序状态,其实还没有保存。可以使用save命令,来在当前的用户环境中,保存pm2的应用程序列表和状态:
js
$ pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/yanjh/.pm2/dump.pm2
这个命令,会将当前pm2程序列表和状态,保存在dump.pm2文件当中。如果系统重新启动,pm2会根据服务配置,找到这个文件,并恢复保存前的状态。
其他扩展特性
PM2提供的功能是非常丰富而强大的,很多特性笔者还没有机会和条件使用,这里由于篇幅限制,简单列举几条,读者有兴趣可以自己深入研究应用:
- 监听应用程序文件夹
在start应用程序的时候,可以使用--watch标签。这个设置可以让pm2监视当前应用程序文件夹内容的变化,并重新启动应用。这个功能在开发和测试环境中非常有用,可以帮助自动加载最新的代码。
- 多实例(cluster)模式
pm2可以在不侵入和修改应用程序代码的情况下,启动和执行多个应用程序的实例。它的工作原理应该源于nodejs程序的cluster机制,因为pm2本身,就是一个nodejs应用程序。
这个特性,可以简单的通过-i选项来实现,如下面的命令可以启动6个程序实例:
pm2 start -i 6 .
这里可以指定实际的实例数量,也可以使用max,或者-1,系统会自动检测可用CPU数量来进行配置。
- 配置文件
可以为PM2编写一个格式为JSON的配置文件,来控制PM2运行应用程序的行为。而不是直接启动应用的入口程序,以提供更丰富的控制功能,如设置环境参数、重启延时、日志路径等等。
pm2 start app.json
- 定时执行或者重启
pm2可以通过 --cron-restart 选项,来控制应用程序的定时执行或者重新启动。因为并不是所有的nodejs程序,都是服务类的程序,还有很多工具类的程序,需要进行定时启动操作。这样,pm2就可以管理各种各样的应用程序的执行和启动,非常灵活而方便。
- 生态系统
可以通过一个配置文件,同时管理在逻辑上可能相关的多个nodejs应用程序。就是所谓批量管理。
- Web Server
笔者在研究中刚刚发现,pm2内置了一个静态文件的Web Server,这样可以省略一个nginx系统了。
pm2 serve path port
这个命令,可以以一个特定的文件夹路径和端口,来提供一个简单的静态Web文件服务。这个功能还支持SPA(Single Program Application, 单页面应用程序)模式,就是所有路径都会被定向到单一HTML文件上,这也是现在前后端分离应用的常见形态。
- 在线服务和监控
pm2.io还提供应用程序管理的在线服务,比如更好的Web管理界面和更丰富的状态监控和性能分析等功能。这些属于一种增值的付费服务内容。
小结
本文分享了一个在nodejs系统运维中常用的管理工具pm2,包括其基本概念,工作方式,特点和主要使用命令和方式等等。