如何将Node.js应用程序作为独立进程运行?
如何将Node.js应用程序作为独立进程运行?
如何最佳部署Node.js?\n我有一个Dreamhost VPS(他们称之为虚拟机),我已经成功安装了Node.js并设置了代理。只要我保持启动Node.js的SSH连接开启,这个方案运行得很好。
问题的原因:文章中提到了使用Nginx作为反向代理来路由请求到同一服务器上的不同应用程序。然而,用户提出了一个问题,即如果服务器上始终只有一个Node网站,是否可以安全地放弃使用Nginx。
解决方法:有人回答说不建议放弃Nginx。除了SSL终止和缓存等功能外,Nginx反向代理还可以在主机前提供更大的基础设施灵活性。它还意味着您不必将Node直接运行在80端口上,这被认为是支持Nginx设置的一个重要原因。
我在这里写了关于我的部署方法:部署Node.js应用
简而言之:
- 使用git的post-receive hook
- Jake作为构建工具
- Upstart作为Node的服务包装器
- Monit用于监控和重新启动应用程序
- Nginx用于将请求路由到同一服务器上的不同应用程序
如果我在服务器上始终只有一个Node网站,我可以安全地放弃Nginx吗?
链接似乎已损坏
我知道这是一个晚回复,但我不会这样做。除了SSL终止和缓存等功能外,Nginx反向代理在主机前提供了更大的基础设施灵活性,而不是直接在80端口上运行Node。这也意味着您不必将Node作为root用户运行,我认为这是支持Nginx设置的一个重要原因。
问题的原因是用户想要将Node.js应用程序作为独立进程运行,并且在进程死亡时能够自动重启。解决方法是使用Forever工具来实现这个目标。Forever可以将Node.js程序运行在独立的进程中,并在进程死亡时重新启动它们。
使用Forever的方法如下:
1. 使用forever start example.js
命令来启动一个进程。
2. 使用forever list
命令来查看所有由Forever启动的进程列表。
3. 使用forever stop example.js
命令来停止一个进程,或者使用forever stop 0
命令来停止索引为0的进程(可以通过forever list
命令查看索引)。
然而,有用户遇到了问题。尽管程序能够成功启动,但无法停止。用户尝试过退出登录并重新登录,然后手动终止Node进程,但Forever并没有重新启动它。原因是Forever本身也是运行在Node上的,所以无法直接终止Node进程。文章的作者在回答中提供了使用方法,包括如何停止一个进程。作者自己在VPS上成功使用了这个方法。
用户尝试使用forever stop 0
命令来停止进程时遇到了错误,导致事情变得一团糟。用户怀疑这可能是由于没有使用root权限以及使用独立用户运行的原因。用户打算进一步研究这个问题。
用户发现自己的npm安装存在问题,导致使用Forever时出现了一些问题。在正确安装了npm和node之后,用户将Forever的启动命令添加到了一个定时任务中,以便在系统重启时自动运行。用户现在正在开发一个小的Node应用程序,用于启动和停止Forever进程。
除了Forever之外,还有一个使用Node的原生集群API的替代工具,名为Naught。用户提供了Naught的GitHub链接。
由于用户不使用Linux机器,所以之前的答案对用户来说没有帮助。用户认为这个答案是唯一适用于所有可以运行Node的操作系统的正确答案,而且设置和使用都非常简单。用户进行了一些测试,发现它能够立即重新启动应用程序,甚至都没有注意到应用程序暂时关闭了一毫秒。
如何将Node.js应用程序作为独立进程运行?
在Linux发行版中,几乎所有都配备了systemd,这意味着forever、monit、PM2等工具不再必要 - 操作系统已经处理了这些任务。
创建一个名为myapp.service
的文件(将'myapp'替换为你的应用程序名称):
[Unit] Description=My app [Service] ExecStart=/var/www/myapp/app.js Restart=always User=nobody # 注意Debian/Ubuntu使用'nogroup',RHEL/Fedora使用'nobody' Group=nogroup Environment=PATH=/usr/bin:/usr/local/bin Environment=NODE_ENV=production WorkingDirectory=/var/www/myapp [Install] WantedBy=multi-user.target
注意:如果你是Unix新手: /var/www/myapp/app.js
文件的第一行应该是#!/usr/bin/env node
,并且需要赋予可执行权限chmod +x myapp.js
。
将你的服务文件复制到/etc/systemd/system
文件夹中。
使用systemctl daemon-reload
通知systemd有关新的服务。
使用systemctl start myapp
启动服务。
使用systemctl enable myapp
使其在启动时自动运行。
使用journalctl -u myapp
查看日志。
这段内容摘自How we deploy node apps on Linux, 2018 edition,该文章还包括了生成AWS/DigitalOcean/Azure CloudConfig构建Linux/node服务器(包括.service
文件)的命令。
有关如何处理Failed to issue method call: Unit name ... is not valid.
的问题?
'unit'的名称与你的服务名称一致。听起来存在差异。在将文件复制到/etc/systemd/system
后,你可能需要运行systemctl daemon-reload
(systemd通常会告诉你是否需要这样做)。说实话,最好将此问题作为一个单独的问题进行询问。
你可以使用systemctl enable /full/path/to/myapp.service
而不是将服务文件复制到/etc/systemd/system
,这将为你创建一个符号链接。
与pm2相比如何?它可以替代pm2吗?pm2是否提供更多必要的功能?
能否逐行解释服务文件给Windows用户?我的意思是ExecStart
是js
文件,但是node
在哪里调用?我有点困惑。
node
是由/var/www/myapp/app.js
自己调用的。在Unix中,如果将一个文件设置为可执行,并且第一行以#!/some/file
开头,那么该文件将使用该二进制文件进行解释。搜索“interpreter Unix”以获取更多信息。
你提到只有systemd,但是其他Linux init系统不是也可以这样做吗?请注意,一些Linux发行版拒绝使用systemd,比如Devuan。如果有人能回答这个问题,将它与pm2相比如何?不使用pm2有一个优点,那就是减少依赖性,这里有一些有趣的答案:stackoverflow.com/questions/4681067/… hashnode.com/post/…
通常情况下,如果不是systemd,就是sysvinit,这意味着需要编写一个shell脚本(参见/usr/share/doc/svsvinit*
),然后添加一个额外的工具来监视和重新启动应用程序。