56

我们目前正在为一个由 node.js/socket.io 应用程序支持的客户开发一个网站(Apache 下的 TYPO3),该应用程序为 CMS 提供的内容提供实时更新。

由于这是我们的第一个 node.js 项目,当谈到“完美设置”时,我没有任何最佳实践可供参考,因此我花了一些时间研究部署技术。

为了实现良好的设置,我还有几个问题:

  1. 易于客户部署。这非常重要,因为我们的网站将集成到他们的“实时”TYPO3 安装中,该安装为大量网站提供服务,并且运行在不受客户管理的服务器上,而是由另一个(集中式)组织进行支持呼叫和服务器更改的组织缓慢的过程。

  2. 应该很容易更新。如前所述,请求重新启动和进行服务器更改是一个缓慢的过程,因此理想情况下,节点安装应该在收到使用git.

部署

普遍的共识似乎是forever在部署节点应用程序以保持它们运行时使用。我已经测试过forever,它似乎在由npm install forever -g(全局)安装时工作正常。不过,这需要外部协助才能在实时环境中全局安装,所以我更愿意让它从应用程序的node_modules目录运行,但我无法创建一个可靠的包装器来执行此操作。

此外,forever工作正常,但必须手动启动。确保它在服务器启动时启动并继续运行的最佳方法是什么?

  • 一个简单的init.d脚本?
  • 编写看门狗包装器?
  • 检查forever状态的 TYPO3 调度程序任务?

快速开发/更新重启

我们目前仍处于项目的开发阶段,每次我对 node.js 应用程序进行更改时,我都会手动重新启动nodeforever. 这可行,但远非理想。有几个较小的npm模块可以检查文件修改并node在检测到更改时重新启动,例如:

有没有人有这些经验?

更新:你为什么不直接使用集群?

Cluster 模块通过重新加载机制提供了类似的功能,但不适用于 Node 0.5+。取代它的核心集群模块(节点 0.6+)不具备所有这些功能,而仅提供集群。这反过来又不能很好地与 socket.io 配合使用。至少在不使用 Redis的情况下不会(这对我们来说是个问题,因为我们不能强制向客户提供另一个 prereq 服务)。

--

forever显然,在将项目移交给客户之前,我正在尝试找到最稳定的解决方案,该解决方案将更新重启程序与之前相结合,我真的希望任何人都已经产生了经过验证的技术组合。

4

3 回答 3

63

结合所有收集到的知识(非常感谢Julian Knight的想法)和过去一周测试的方法,我决定接受下面描述的部署解决方案(我想我很乐意分享以帮助其他有类似问题的人):

脚本错误时自动重启脚本更改时自动重新加载由 forever处理,因为它还包括脚本监视,只要 Forever 是从 node.js 脚本中生成的。

为此,我添加了一个server.js来启动app.js我们实际想要运行的脚本:

服务器.js

var forever = require('forever'),
    child = new(forever.Monitor)('app.js', {
        'silent': false,
        'pidFile': 'pids/app.pid',
        'watch': true,
        'watchDirectory': '.',      // Top-level directory to watch from.
        'watchIgnoreDotFiles': true, // whether to ignore dot files
        'watchIgnorePatterns': [], // array of glob patterns to ignore, merged with contents of watchDirectory + '/.foreverignore' file
        'logFile': 'logs/forever.log', // Path to log output from forever process (when daemonized)
        'outFile': 'logs/forever.out', // Path to log output from child stdout
        'errFile': 'logs/forever.err'
    });
child.start();
forever.startServer(child);

这将监视应用程序目录中的所有文件的更改,并在更改后forever立即重新启动正在运行的脚本。由于日志和 pidfile 位于应用程序的子目录中,因此必须从文件监视中忽略它们,否则脚本将循环重新启动:

.foreverignore

pids/**
logs/**

为了让这一切在系统启动时开始,使我们能够start node-app使用stop node-appUbuntu的 Upstart轻松控制服务。我将两个示例(这个这个)组合成一个可以很好地完成工作的示例:

/etc/init/node-app.conf

# This is an upstart (http://upstart.ubuntu.com/) script
# to run the node.js server on system boot and make it
# manageable with commands such as
# 'start node-app' and 'stop node-app'
#
# This script is to be placed in /etc/init to work with upstart.
#
# Internally the 'initctl' command is used to manage:
# initctl help
# initctl status node-app
# initctl reload node-app
# initctl start node-app

description "node.js forever server for node-app"
author      "Remco Overdijk <remco@maxserv.nl>"
version "1.0"

expect fork

# used to be: start on startup
# until we found some mounts weren't ready yet while booting:

start on started mountall
stop on shutdown

# Automatically Respawn:
respawn
respawn limit 99 5

env HOME=/home/user/node-app-dir

script
    # Not sure why $HOME is needed, but we found that it is:
    export HOME=$HOME
    chdir $HOME
    exec /usr/local/bin/node server.js > logs/node.log &
end script

#post-start script
#   # Optionally put a script here that will notifiy you node has (re)started
#   # /root/bin/hoptoad.sh "node.js has started!"
#end script

正如Kevin 在他的文章中明智地提到,以 root 身份运行 node 是不明智的,因此我们将exec sudo -u www-data /usr/local/bin/node在下周迁移到新服务器时将其更改。

因此,它forever会自动node server.js启动,由 启动upstart,并监控崩溃和文件更改,让整个设置运行只要我们想要的时间。

我希望这对任何人都有帮助。

于 2012-06-22T13:33:40.193 回答
7

因为我的最后一个答案是为了未来!以下是一些其他帮助链接:

似乎还没有一个完美的答案,但是有很多人在运行生产节点实例。希望这将为您指明正确的方向。

于 2012-06-19T21:49:17.083 回答
5

对于生产用途,您可能会更好地查看Cluster之类的东西。您可能不需要集群功能,但它还包括其他生产功能,例如零停机重启、日志记录、工作程序等。

正如您所说,Forever 可以进行测试,但实际上并没有生产使用所需的东西。

我似乎隐约记得,从 v0.7 开始,Node 本身可能会采用 Cluster 或类似的东西

于 2012-06-18T20:26:54.403 回答