部署一个生产Node.js服务器

Deploying a production Node.js server

本文关键字:Node js 服务器 一个 部署      更新时间:2023-09-26

我已经写了一个Node.js应用程序,我希望让它运行在我们的生产机器之一。这似乎是一个相当普遍的要求,但我找不到一个适当的解决方案。是否没有部署生产Node.js应用程序的既定解决方案?

该应用程序很简单(<100 LOC),但需要非常高效,可靠,并且可以连续运行多年而无需重新启动。它将在一个大型网站上运行,每秒有几十个连接。(该应用程序不用作web服务器,它只有一个JSON API)

以下是我考虑过的方法,但我仍然不确定:

使用框架(例如:表达)

因为应用程序需要高性能并且非常简单,所以以框架的形式添加膨胀是我想要避免的。

使用nohup

启动服务器

这里的主要问题是异常处理,我们(显然)不希望整个服务器因为异常而崩溃。据我所知,将整个应用程序包装在try {} catch {}循环中不会有帮助,因为Javascript解释器在异常后处于不可预测的状态。对吗?

使用Forever

我在我们的FreeBSD机器上安装了Forever,它有很多bug。它最终会产生无尽的进程,而这些进程是永远都无法消灭的。我不得不运行kill -9来恢复我的机器,我对在Forever上运行生产应用程序不太有信心。Upstart(类似的工具,但更通用)似乎也不能在FreeBSD上运行。

托管解决方案(例如;Heroku, Rackspace, Amazon EC2等)

这可能是最简单的解决方案,但我们已经为其余的web服务器提供了一个严肃的硬件。从经济上考虑,这是没有意义的。

肯定有既定的解决方案吧?我错过什么了吗?

  • 你真的应该使用一个框架(我推荐像Express这样的东西,因为它是经过实战测试的),除非你想自己处理会话、cookie、中间件等。快递真的很轻。
  • 用nohup启动服务器:你不应该这样做,只需要用常规的"node"命令启动它。此外,Express将路由封装在try-catch中,这样您的服务器就不会在路由中崩溃。然而,如果你的服务器确实有一个严重的问题,你不应该害怕重新启动它(此外,如果你至少有2-3个进程,只有一个会死亡,所以至少有1-2个剩余的用户不会感觉到什么)。
  • 对于监控,我个人更喜欢操作系统级别的东西,如Upstart和Monit。
  • 主机解决方案:既然你已经有了自己的硬件,就不需要投资其他东西了。只需使用负载均衡器(可能是nginx或node-http-proxy)来代理内容。

参见Hosting Node Apps。

本教程将引导您设置一个服务器,该服务器可以为服务器端JavaScript应用程序托管node.js应用程序。现在,node.js托管选项归结为运行与web服务器通信的节点守护进程。大多数web服务器可以代理连接到不同的端口,所以你可以使用Apache或nginx来做到这一点。

尝试使用pm2它是简单直观的CLI,可通过NPM安装。只要用PM2启动你的应用,你的应用就可以处理大量的流量了

PM2官方链接

如何使用pm2设置一个用于生产的node js应用程序

我想这里有三个问题。

问题0:"我应该为我的node应用使用框架吗?"

问题1:"如何在生产机器上运行节点服务器?"

问题2:"如何将节点应用部署到生产环境中"。

对于问题1,我非常喜欢Cluster(尽管最新的Node版本内置了类似的功能,所以您可以检查一下)。我已经成功地使用了像Monit/Upstart这样的工具来监控操作系统级别的事件,并确保你的服务器处于良好的健康状态。(这是监视N个Ruby Thin服务器集群,但同样的事情)。

根据流量,您可能希望在多台机器上运行集群,然后在其前面放置负载平衡器。这取决于您的流量,完成请求需要多长时间/阻塞事件循环需要多长时间,以及每台机器启动多少处理器/节点实例。

框架提供了更好的错误处理,并捕获了会退出正常node.js应用程序的错误。如果你在没有框架的情况下这样做,请确保你阅读了node.js中的错误处理。

对于问题2,我认为节点社区还没有一个好的部署标准。您可以尝试使用Ruby的Capistrano工具(这里有一篇博客文章讨论如何使用Capistrano部署集群)。

Capistrano的缺点是它做了一些可能不正确的假设(例如:你正在部署一个Rails项目),所以你可能最终会与框架进行多次斗争。

我的goto部署解决方案通常是Python的Fabric工具,它为你提供了部署工具,让你做你需要做的事情。

另一个部署选项是"云",像Nodester这样的东西:让他们照顾它。

您可能会在ServerFault上得到更好的答案,但是这里有一个使用supervisord的用户体验的描述。您将需要使用某种进程监视器来保持node进程的活动,另一个常见的建议似乎是以某种方式反向代理连接到node进程。我可能会投票给nginx(这样您就可以让nginx处理日志记录、身份验证或任何其他您需要的高级HTTP特性,而不是将它们放入节点中),但是前面的文章在评论中提到了haproxy,它可能更轻量级。你对反向代理的选择很大程度上取决于你是否需要WebSocket支持。

我不确定是否有更多的"标准"工作流存在于节点;它不像Rails那样成熟,Rails有无数种方法来保持web应用程序的运行。

Cloudkick的家伙写了一个很好的解决方案。它叫Cast, http://cast-project.org/。

在服务器和工作站上安装cast。在服务器上启动铸造代理,并让工作站使用服务器铸造实例进行签名。然后你可以创建"bundle",将它们上传到服务器,创建/升级/销毁它们,以及启动/停止你的实例。Cast将在服务崩溃时自动重新启动。您还可以远程跟踪stdout/strerr,获取正在运行的实例和PID#的列表,并从工作站管理您的实例/服务器(不需要ssh)。这些文档有点过时了,但结果值得你付出额外的努力。所有的交互/命令都通过HTTPS和RESTful API。

在此之前,我用SCP/SSH手工做所有的升级。我们有supervise在跟进。我们没有回头。