技术开发 频道

构建Node.js应用的10个重要的方面

        【IT168 评论】应用程序需要有个明确目标,能帮干活能解决问题。这一点同样可以用于你决定去做的每件事上。目标明确根基夯实,应用程序才会越做越好。明确的目标会帮你闯出出一条如何正确解决问题的道路、也让你在遇到阻碍陷入困境无法前行的时候依然坚定执着着望向远方。

  架构

  架构会考虑到源代码的设计,文件排列,程序库/模块使用,他们交织在一起编织出了应用程序。架构形式会随着应用程序的开发不断发生变化,它可能是一个web应用服务器,像express这样的处理静态资源(比如图片),也可能是一个scheduler/worker pipeline,排队以及处理队列中的项。

  无论何种目的,都有一些通用的原则应该遵守。

  模块化。尽量保证你的代码遵守DRY原则(Don't Repeat Yourself(不要重复自己))。如果你发现你需要在许多不同的地方使用一段相似的代码,通常应该将他们放在一个单独的文件(或模块)的一个函数中,从而形成通用帮助函数集模块。这个模块可以在其他依赖它的地方使用require()函数来加载。这样做的目的不仅仅是防止多次重写相似的功能,并且当你升级功能时,你只需要修改同一个函数即可。

  遵守Node规范,尽量保证第三方node模块放在node_modules文件夹下。同时也应该保证node_modules在你的.gitignore里,这样你就不会提交不相干的依赖文件。

  分离关系。前端相关的内容(静态CSS,javascript,HTML,模板文件,图片,资源文件)应该与后端应用逻辑(路由,服务器,中间件)分离。同样的,应该将部署脚本,配置文件,数据关系文件和测试文件分开放置。

  部署

  你应用到生产环境的方法很大程度上依赖于你堆栈的性质。以下是我们尝试过的一些方法:

  手动通过SSH传到服务器和拷贝git仓库。优点:全手动控制,零部署工具设置。缺点:大量服务器时难以实施。所有的事情都需要手动设置,因此你不会得到任何好处,像upstart / initrc supervisation或者没有日志的运行。

  Capistrano.优点:对于团队开发者来说是标准的流程,只需简单的运行:cap deploy。缺点:难以配置,需要Ruby依赖。

  Chef 脚本. 优点:通过脚本安装程序。缺点:每次想部署时,需要重启服务器。Chef最常被用于服务器的安装/配置,而不是应用程序部署。

  Deliver. 当我们厌倦了其他的一些操作时,我们可以使用GoSquared出品的这个部署工具。

  它的灵感来自于Heroku’s的git推送系统的基础部署。你只需要为应用程序配置一个系统用户(那些你需要做的——我们都帮你自动做好了),建立一个基本的分发配置,在工程里运行分发的命令行。它使用git通过SSH把应用程序推送到你的服务器,可以使用 foreman或者equivalent来监听应用程序的启动,复位和恢复。

  这并不是一个详尽的部署方案的列表,你可能需要发挥一点创意来构想一个最适合您自个需求的解决方案。无论你采用何种策略,将部署配置文件纳入您的应用程序的源代码版本控制并将部署流程记录在您的README文件中都是一个好主意。

  配置

  几乎每个应用程序都有一些常量和设置需要能被方便地更改。常见的有主机名,端口号,超时时间,模块选项和错误。在一个地方保存这些值将非常有利,可存在一个文件或多个文件中,如果这些值足够多。这样做可以使他们能更快地被修改,而不必花时间在梳理代码以跟踪查找到它们。

  我之前只是转储配置的设置到一个输出配置属性为对象的文件。这在一个非常特殊的环境下运行良好,比如在生产环境的时候,但随着时间的推移,这开始成为维护的一个瓶颈,变得没有条理性,并且在应用改变时产生了多个文件作为一个基础设施。

  我们可以通过环境配置获得想要的结果,这个想法是指你可以在应用程序运行时修改基于环境的配置值。这个方式很简单,输出一个叫做$NODE_ENV 的shell环境变量包含一个你将要运行程序的环境模式标识。你的应用程序将定制配置的设置,当它启动时使用你定义好的环境。

  环境方面的配置为你提供了贯穿整个应用程序生命周期的更多的灵活性,你应该可以在本地开发和运行你的应用程序,而不需要网络连接(你想要在火车上能够进行?事实上写这篇文章时我正好在火车上),这需要为本地服务指定主机地址和端口号。然后,你可能会希望在部署到服务器之前能够进行测试。这些都需要不同的配置。

  我们一般使用 node-config,一个为工作精确设计的模块。所有你需要做的是在config/default.js中定义配置的值,接下来为你不同的环境建一个文件,包含继承了default.js的默认指令。你设置$NODE_ENV作为环境变量的名字,这个模块会覆盖defaults.js中定义的[$NODE_ENV]属性。导入到你的应用程序合并配置对象,你只需使用require()就可以。

  日志,度量和监测

  你想给自己足够的应用的不正常行为的证据,以至于你就可以在尽可能很少的时间内使‘b0rked’变为”所有错误已经修正“。一个最好的办法是依赖日志。通常的前提是,如果得到了错误,记录它。你必须遵从node的错误处理规则,在Callback的第一个章节已经预设了当一个错误发生时的错误信息:

  不管怎样,如何应对错误完全在于你。你或许想记录错误,然后继续。或者你想终止执行这个回调。无论如何,你应该在未来应用这些错误,而且记录日志是最简单的实现方式。

  尽管记录错误日志是一个很好的方法,但是也会导致大量的消息被发送到logs日志或者终端。TJ Holowaychuck开发了一个叫做 debug的模块,允许为日志消息创建命名空间,通过这途径,我们就可以过滤掉不必要的消息,而通过命名空间抓取我们需要的消息。TJ的 repertoire还有大量其他模块。

  指标

  应用指标为我们提供了有用的信息,以便查看应用在做什么操作和这些操作的时间间隔。它给我们提供一个重要的途径去检测异常的事件,瓶颈还有扩充收缩计划的参考。我将这些归结到一个小的模块,叫做abacus,它可以帮助我们维护计数器的集合,并通过statsd把它们以可视化绘图形式描绘到graphite。实践证明,保证应用在给定的参数下运行时非常方便。

  监测

  监测并非是必需的,但是监测是一个很好的途径,让我们了解运行应用的服务器的资源使用率。另外的早期警告系统,同样非常重要,可以让我们避免一些低级问题而导致的应用崩溃。没有比服务器硬盘空间不足而导致的应用崩溃,或者CPU使用超过负载而崩溃,而更让人窘迫。

0
相关文章