PM2集群模式配置问题及解决方案
之前曾撰写过一篇关于Nuxt3的文章,其中提到了PM2的环境变量配置。最近我有空再次验证了一下,发现之前的一些配置存在问题,因此在此做一个勘误。
在PM2的启动配置中,有一个名为
exec_mode
的选项,默认值为
fork
,另一个可选值是
cluster
。其中
fork
是单进程模式,
cluster
是多进程模式,也就是常说的集群模式。
最初使用Nuxt3时,由于文档不够完善,很多配置都是参考Nuxt2的,导致了一些问题。具体来说,之前的配置造成了一些CPU占用过高的问题。通过查看CPU占用情况,发现是由于node进程导致的。进一步定位到PM2,发现多个进程只有一个启动成功,其他的进程都在反复重启,导致CPU升高。进一步查看日志发现是因为端口被占用导致只有一个进程能启动成功。因此,我意识到配置可能存在问题,但当时没有时间调整,因此一直以来都是通过手动停止其他进程来解决问题。
为了解决问题,我再次翻看了Nuxt3的文档,看下官方是怎么配置PM2的。最初我并没有意识到问题出在启动脚本这里,直到我找到了一个GitHub上的issue "Port Already in Use in Cluster Mode",其中提到不应使用npm来启动,而是直接使用脚本路径。
通过npm启动时,并没有将这个进程直接托管给PM2,而是通过npm启动了一个进程,PM2只是监控这个进程,因此PM2并不能很好地管理这个进程。因此,我意识到需要对启动脚本进行调整。
关于集群模式,最初我怀疑是集群模式的问题,但即使改成fork,也还是会出现端口占用的报错。虽然可以通过修改
instances
来解决,但隐约觉得不是正确的方法。在解决启动报错问题之后,我再次尝试了使用集群模式,但仍然不太清楚是否应该使用这个配置。因此,我做了一些测试,只是在本地环境的一些测试,结果并不准确,只能做个参考。
使用
pm2 monit
监控进程,可以看到这时还没什么区别。然后用jmeter进行压测,创建500个线程访问集群模式的进程,可以看到两个进程都在运行。
然后同样的压测,但是使用fork模式,可以看到只有一个进程在运行。
通过简单的测试并没有感受出优劣,集群的优势可能体现在性能和容错方面,在硬件上看不出太多效果。这里只是做一个记录,具体还需要更多的实践经验。
集群模式允许联网的Node.js应用程序(http(s)/tcp/udp服务器)在所有可用的CPU上扩展,无需任何代码修改。根据可用CPU的数量,这将极大地提高应用程序的性能和可靠性。