Node.js设置,方便部署和更新
我们目前正在为一个客户开发一个网站(Apache下的TYPO3),该客户受到node.js / socket.io应用程序支持,该应用程序可以实时更新从CMS提供的内容。
由于这是我们的第一个node.js项目,所以我没有任何最佳实践,所以我花了一些时间研究部署技术。
我仍然有几个问题要达到一个好的设置:
-
很容易为客户部署 。 这是非常重要的,因为我们的网站将被集成到他们的“实时”TYPO3安装中,该服务提供了大量的网站,并且运行在不是由客户pipe理的服务器上,而是另一个(支持呼叫和服务器更改的)缓慢的过程。
-
应该很容易更新。 正如前面所提到的,请求重启和更改服务器是一个很慢的过程,所以理想的情况是,当节点安装接收到使用
git
压入活安装的更改时,应该重新启动/更新。
部署
普遍的共识似乎是在部署节点应用程序以保持其运行时forever
使用。 我已经testing了forever
,它似乎工作正常,安装通过npm install forever -g
(全球)。 虽然这需要外部的帮助来在全球范围内安装,所以我宁愿从应用程序的node_modules
目录运行它,但是我还没有能够创build一个可靠的包装器。
此外, forever
工作正常,但它必须手动启动。 确保服务器启动并保持运行的最佳方法是什么?
- 一个简单的
init.d
脚本? - 写一个看门狗包装?
- TYPO3调度程序任务,
forever
检查状态?
快速开发/重新开始更新
我们目前还处于项目的开发阶段,每次我对node.js应用程序进行更改时,都会手动重新启动node
或forever
重新启动node
。 这工作,但远非理想。 有几个较小的npm
模块检查文件修改,并检测到更改后重新启动node
,如:
- Nodemon
- Node.js主pipe
- 弹跳
- 结节 (不需要重新启动节点,因此可能更容易与
forever
结合) - 向上
有没有人有这些经验?
更新:为什么你不使用群集?
群集模块通过重载机制提供类似的function,但不适用于Node 0.5+ 。 replace它的核心群集模块(节点0.6+)不具有所有这些function,但仅提供群集function。 而socket.io反过来又不好用 。 至less不是没有使用Redis (这对我们来说是一个问题,因为我们不能强制给客户另外的prereq服务)。
–
显然,我试图find最稳定的解决scheme,结合更新 – 重新启动程序与forever
将项目交给客户之前,我真的希望任何人已经产生了一个成熟的技术组合。
结合所有收集到的知识(非常感谢Julian Knight的观点)和过去一周testing的方法,我已经决定解决下面描述的部署解决scheme(我认为我会很高兴分享以帮助其他人提出类似的问题):
脚本错误自动重新启动和脚本更改自动重新加载永远处理,因为它还包括一个脚本监视,只要从一个node.js脚本内生成Forever。
为此,我添加了一个server.js
来启动我们实际想要运行的app.js
脚本:
server.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);
这将监视应用程序目录中的所有文件以进行更改,并在更改后立即重新启动运行的脚本。 由于日志和pid文件位于应用程序的子目录中,因此必须从文件监视中忽略这些日志和pid文件,否则脚本将循环重新启动:
.foreverignore
pids/** logs/**
为了使这一切都从系统启动开始,并使我们能够使用start node-app
轻松控制服务,并stop node-app
我们使用Ubuntu的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身份运行节点是不明智的,所以我们将在下周移动到新服务器时将其更改为exec sudo -u www-data /usr/local/bin/node
。
所以,一开始就会由node server.js
自动启动,并监视崩溃和文件变化,保持整个设置运行,只要我们想要。
我希望这可以帮助任何人。
因为我最后的答案是未来! 这里有一些其他的链接来协助:
- https://serverfault.com/questions/274857/how-to-use-node-js-as-a-production-web-server
- http://www.slideshare.net/the_undefined/nodejs-best-practices-10428790 (见幻灯片35)
- http://www.slideshare.net/the_undefined/nodejs-in-production (幻灯片31到最后)
- 当node.js发生故障时,如何自动恢复?
目前还没有一个完美的答案,但是有很多人在运行生产节点实例。 希望这会使你指向正确的方向。
为了生产的使用,你可能会更好看一些类似Cluster的东西。 您可能不想要群集function,但它也包括其他生产function,如零停机重新启动,日志logging,工作人员等。
正如你所说,Forever可以testing,但实际上并没有什么生产用途。
我似乎隐约记得,集群或类似的东西可能被采纳到Node本身来v0.7