【问题标题】:Node.js reliability for large application大型应用程序的 Node.js 可靠性
【发布时间】:2012-03-22 10:27:24
【问题描述】:

我是 Node.js 的新手,目前正在质疑它的可靠性。

根据我目前看到的情况,似乎存在一个重大缺陷:任何未捕获的错误/异常都会导致服务器崩溃。当然,您可以尝试对您的代码进行防弹或将 try/catch 放在关键区域,但几乎总是会有漏洞从裂缝中溜走。如果一个有问题的请求会影响所有其他请求,这似乎很危险。我发现了两种解决方法:

  1. 使用守护进程或模块,如forever,在服务器崩溃时自动重启服务器。我对此不满意的是服务器仍然关闭了一两秒(对于大型网站,这可能是数百(数千?)的请求)。

  2. 使用process.on('uncaughtException') 捕获未捕获的异常。这种方法的问题(据我所知)是无法获取对导致异常的请求的引用。因此,该特定请求被挂起(用户看到加载指示器直到超时)。但至少在这种情况下,其他没有问题的请求仍然可以处理。

任何 Node.js 资深人士都可以参与吗?

【问题讨论】:

  • 我不相信大型网站上有“数十万”个丢失的请求。大型网站将横向扩展,因此单个进程只会影响总流量的一小部分。
  • 可能重复:stackoverflow.com/questions/7310521/… stackoverflow.com/questions/9181027/… 虽然我似乎理解接受的答案不令人满意?
  • @Kevin 可能仍然有数百个,或者无论如何根本无法接受
  • 正如 JP 所说,Nodejs 具有集群支持 nodejs.org/api/cluster.html 也有可以由主进程重新启动的子进程。
  • 我也很担心这个问题——这就是为什么我在一个新项目中犹豫使用 Node.js 作为 REST api 的原因。

标签: javascript node.js


【解决方案1】:

对于自动重启和负载平衡,我建议您查看Learnboost's up balancer。

它允许您在负载均衡器后面重新加载工作器,而不会丢弃任何请求。它停止将新请求定向到工作线程,但对于已经在处理的现有请求,它提供workerTimeout 宽限期以等待请求完成,然后才真正关闭进程。

您可以调整此策略,使其也由uncaughtException 事件触发。

【讨论】:

  • 在许多情况下,最好让节点因意外异常而崩溃,并且像 up 这样的重启对访问者来说是不可见的。当我将 nginx 用于 php 页面时,我了解到 php 工作人员总是崩溃,而作为 apache 用户,您不知道这一点,因为 apache 显然与 up 做同样的事情。让我觉得 apache 可能可以配置为节点 hmmm....
【解决方案2】:

您可以完全控制基本流程,这是一项功能。

如果将 Node 与 Apache/PHP 设置进行比较,后者实际上相当于拥有一个简单的 Node 服务器,它将每个传入请求发送到它自己的进程,该进程在处理请求后终止。

如果您愿意,您可以在 Node 中进行设置,在许多情况下,这样的设置可能是个好主意。 Node 的伟大之处在于您可以打破这种模式,例如,您可以让主进程或另一个永久进程在将请求传递给它的处理程序之前进行会话处理。

Node 是一个非常灵活的工具,如果你需要这种灵活性,那很好,但它需要一些技巧来处理。

【讨论】:

  • 是的,这是一把双刃剑……大多数被 Node 吸引的人不一定具备正确构建“正确”服务器设置的知识或愿望。就像在发生某些事情之前没有人真正关心最近的 Ruby 安全漏洞一样。我个人很喜欢 Node,因为我非常熟悉 Javascript。我觉得应该有多种开箱即用的 Node 来处理各种场景。
【解决方案3】:

异常不会使服务器崩溃,它们会引发异常。

node.js 中导致整个过程中断的错误是另一回事。

您最好的选择(您应该使用任何技术)就是尽快用您的应用程序对其进行测试,看看它是否适合。

【讨论】:

    【解决方案4】:

    如果未捕获到未捕获的异常,则会导致服务器崩溃。类似于调用拼写错误的函数。我使用process.on('uncaughtException') 来捕获此类异常。如果你使用它,是的,发送到process.on('uncaughtException') 的错误信息较少。

    我通常包含一个像nomnom 这样的模块来允许命令行标志。我包括一个名为--exceptions 的函数,它在设置时会绕过process.on('uncaughtException')。基本上,如果我看到未捕获的异常正在发生,那么我在开发中使用--exceptions 启动应用程序,以便在引发该错误时不会被捕获,这会导致 Node 吐出堆栈跟踪然后死掉。这会告诉您它发生在哪一行,在哪个文件中。

    捕获异常是处理它的一种方法。但是,就像你说的那样,这意味着如果发生错误,可能会导致用户没有收到响应,等等。我实际上建议让错误使服务器崩溃。 (我在应用程序中使用process.on('uncaughtException'),而不是网络服务器)。并使用forever。事实上,最好让网络服务器崩溃,然后公开您需要修复的内容。

    假设您使用 PHP 而不是 Node。 PHP 不会突然使服务器崩溃(因为它并没有真正提供服务)。它吐出非常丑陋的错误。当然,它不会导致整个服务器宕机然后必须重新启动。没有人希望他们的客户有任何停机时间。但这也意味着问题将持续存在并且不太明显。我们都看到过说错误的网站,而且它们没有很快得到修补。如果这样一个 bug 只是为了一个小插曲(老实说,这在更大的图片中并没有那么糟糕),那么它肯定会引起人们的注意。你会看到它发生并跟踪那个错误。

    事实上,任何系统中都会存在错误,与语言或平台无关。为了让你知道它们发生了,它们可以说是致命的更好。随着时间的推移,它会让您更加了解这些错误是如何发生的。我不了解你,但我认识很多 PHP 开发人员,他们一次又一次地犯同样的常见错误。

    【讨论】:

    • IMO 网站永远不应该关闭。
    猜你喜欢
    • 2014-10-25
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多