PM2:明智地处理流程管理问题

就在几个小时前,我就Node.JS对于大型项目而言速度太慢而开始辩论,它应该更喜欢Golang,Rust,PHP等。 争议另一端的主要论点是JavaScript是单线程的事实。 据称,在开发应用程序时,性能仅取决于这种单线程,并且无法执行任何操作-只需用其他某种语言重写即可。 但是,NodeJS的情况要比乍看起来好一点。 在深入探讨该主题之前,我想声明,我尊重每个开发人员使用他喜欢的并且在特定任务中认为更可取的编程语言的权利。

在Habr上搜索了关键字“ PM2”之后,我没有发现任何有关此过程管理器的文章。 其他用户的文章中只有一个参考。 我对在Node.JS后端开发的这个黑暗角落追赶并摆脱困境的想法感到兴奋(强烈告诉我)(很多人都知道,是的,我知道)。 我问每个对猫有兴趣的人。



关于PM2本身的几句话



PM2是根据AGPL-3.0许可获得许可的开源过程管理器。 据NPM称,在撰写本文时,它每周约有35万次下载。 它主要用于需要在NodeJS上运行应用程序而不必理会的环境中(您也可以将其与其他语言一起使用,但稍后再介绍),这允许您对应用程序进行集群并在处理器内核之间灵活分配负载。 来自GitHub上PM2存储库的一小段剪辑:

PM2是带有内置负载平衡器的Node.js应用程序的生产过程管理器。 它使您可以使应用程序永远保持活动状态,无需停机即可重新加载它们,并简化常见的系统管理任务。


在开发过程中,许多新手在将应用程序“推出”到生产服务器后不知道如何“永久”启动它时遇到了问题。 他们在SSH控制台中编写了set NODE_ENV=production && node app.js ,一切正常,该应用程序正常运行。 关闭控制台,该应用程序将不再起作用。 StackOverflow问题- 如何永久运行node.js应用程序? 总共获得超过23.7万的观看次数。

PM2用一个命令解决了这个问题:

 pm2 start app.js 


该命令“妖化”(从英文“妖妖化”)NodeJS进程,监视其内存消耗并考虑处理器负载。

回到我们的公羊



随着后端负载的增长,有必要在垂直和水平方向上对其进行缩放,以适应这种情况。 众所周知,一个进程可以使用多个处理器内核,但前提是该进程内部有多个线程。 在NodeJS应用程序中,流程是其中之一。 PM2可以在这种情况下提供帮助,并在多个处理器内核之间分配负载。 仍然只有一个命令:

 pm2 start app.js -i max 


在这种情况下, max参数对应于处理器内核的数量。 即 将为8核处理器创建8个独立的进程。 您还可以设置-1而不是max,然后进程数将对应于核心数减去1 。 所有的魅力在于HTTP(S)/ Websocket / TCP / UDP连接将在这些进程之间平均分配。 为什么不水平缩放? 您可以在此处阅读有关PM2群集的更多信息-PM2群集模式

cluster_mode

您可以运行任意多个进程,但是仍然建议遵循“每个内核一个进程”的建议。

尊重记忆


用PHP开发时,我曾经遇到一个问题。 由于经验不足,他下意识地在系统引擎中放置了一个错误,由于这个错误,在某些情况下,进程开始占用过多的RAM。 除此之外,还加载了处理器,因此虚拟机刚刚挂起,因此我根本无法访问它。
正如PHP开发人员所知道的那样,您可以在PHP-FPM中指定进程的分布类型(如果您突然不知道,那么在PHP-FPM中将为每个新请求创建一个新进程)-静态,设置最小和最大阈值时以及动态-分配多少尽可能多的大型过程。 如果启动8个进程并且所有这些进程都开始占用大量内存,那么PM2中会发生什么? PM2能够解决此问题-只需在命令行上使用一个参数即可:

 # Set memory threshold for app reload pm2 start app.js -i max --max-memory-restart <200MB> 


每次达到内存限制时,PM2将自动重新启动该过程。 分配内存比处理容易,不是吗? 8个进程* 200兆字节= 1.6兆字节 二等数学。

除了重新启动进程外,您还可以配置在N个时间间隔后重新启动。 我还没有弄清楚在什么情况下可以派上用场,但是请随时在评论中为我举几个例子:)

如果我重新启动虚拟机?


惊喜! PM2还可为您解决此问题。 在控制台中仍然只有一个命令:

 pm2 startup 


PM2将生成一个脚本,该脚本将在操作系统启动时引发所有必要的进程。 但是,您应该保持警惕-升级Node.JS版本时,所有内容都可能中断。 为避免这种情况,在成功升级到新版本的Node.JS之后,请运行pm2 unstartuppm2 unstartup pm2 startup 。 您可以在链接-PM2启动脚本生成器上阅读有关此内容的更多信息。

进行更改时是否需要手动重新启动集群?


当然不是! 好吧,更准确地说,您当然可以手动重新启动应用程序,但是为什么呢? 力所能及的一切都将自动化,并伴随力量!

 pm2 start env.js --watch --ignore-watch="node_modules" 


将本地存储库中的master分支与远程存储库中的master分支合并时,可以使用此功能。 在我的辅助项目中,这很简单git pull origin master && npm run build 。 当更改服务器/构建客户端/构建文件夹中的文件时,这些过程将自动重新启动。 我知道这是一个非常简单的功能,在本文中甚至不值得提及。 我将使用一些严肃的方法对其进行稀释,并写道:如果使用群集,那么所有进程将依次重新启动。 是的,因此其中至少有一个将始终可用。 这是零停机时间部署!

而且您无法重新启动进程。 对此有重新加载(类似于nginx重新加载):

 pm2 reload all 


团队太多! 一般来说,我更喜欢配置


我已经厌倦了提出有趣的短语,因此它既简单又陈腐:有一个生态系统文件。 支持的格式为JSON,YAML和JS。 例如,当您需要监视服务器客户端文件夹中的文件时:

 module.exports = { apps: [{ script: "app.js", watch: ["server", "client"], env_production : { "NODE_ENV": "production" } }] } 


有关更多信息,请参见链接-PM2应用程序声明

甚至监控!


没有一个。 选择最喜欢的一个。 您可以使用以下命令在控制台中进行监视:

 pm2 monit 




或使用完整的基于Web的监视版本:



您当然不会相信我,但是它是通过以下命令安装和启动的:

 pm2 plus 


还有更多...


宣布支持Heroku和Docker,自动端口增量以及转移到process.env的能力(当您需要在单独的端口上运行每个进程时),在同一OS中启动多个PM2实例,存在软件API以及运行妖魔化的Bash和Python脚本的能力!

我可能错过了其他重要或有趣的内容,您可以随时在评论中提醒我。 我希望您能够从本文中学到一些新知识。

Source: https://habr.com/ru/post/zh-CN480670/


All Articles