Node.js应用的持续部署

翻译前

翻译自:https://blog.risingstack.com/continuous-deployment-of-node-js-applications/

正文

持续部署是...

不,让我们退一步来看持续集成、持续交付、持续部署的区别。

持续集成

持续集成是一天多次/持续地把开发的成果和主分支合并到一起的过程。有助于:

  • 尽早捕获异常
  • 防止「集成地狱」

大部分工作是靠自动测试完成的。

持续交付

持续交付是只将代码部署到一个可以被QA团队或者客户审查的环境。当改动被批准,他们才可以被部署到生产环境。

持续部署

你可以把持续部署看成是持续交付的下一步。在这一步,传递到自动测试的变更会被自动地部署到生产环境。持续部署非常依赖于某些基础设施,这些基础设施将测试、集成、部署新功能的过程自动化。

在这篇文章里,我们将梳理这些自动化步骤、讲述大部分的原则。

一个简化的持续部署工作流如下:

从源代码控制到生产环境

假设我们要做这样一件事,当一个新的功能将要被开发出来并且我们想看到它运行在生产环境。我们要看一下这个代码变更从提交到在生产环境运行起来的全部声明周期。

一切从一次提交开始

每次将代码提交到主分支,都应该触发一个包含测试的新构建。但是当添加新的功能时,你不会想在生产环境中看到半成品的功能。

功能开关

为了解决这个问题,持续部署的创建一般伴随着功能开关。功能开关是指一个切换功能,可以允许开发者发布包含未完成内容的产品版本。这些未完成的功能会被生产环境中的开关隐藏起来。

// 用一个伪造的例子来讲述风格切换
// https://www.npmjs.org/package/feature-toggles var featureToggles = require('feature-toggles');
// 定义切换
var toggles = {
foo: true,
bar: false
}; // 把它们加载到模块中
featureToggles.load(toggles); // 检查某个功能是否被开启
if (featureToggles.isFeatureEnabled('foo')) {
// do something
}

当这个功能已经完成,这个功能开关可以被移除。

持续部署工具

但是在哪触发一个新的构建呢?针对这个例子,你需要一个持续集成工具。已经有很多现成的工具,如 JenkinsTravisCodeshipStrider,其中Strider是用Node.js编写的,Jenkins和Strider是开源的,可以在你的基础设施上进行操作。

当前,我们在闭源项目使用Strider,开源项目使用Travis。

上述每个工具都支持提交钩子,所以现在就创建一个吧!如此一来,你的持续集成工具不用像平常一样拉取代码。

提交时构建

当你选的工具收到了一个新的提交通知,它会启动一个新的构建。构建可以包含很多步骤,有些可以同时运行。说到Node.js应用,将经历如下步骤:

  • 从NPM安装依赖(公共的或者私有的)
  • 运行单元测试
  • 构建静态资源,如css和JavaScript
  • 运行集成测试和端到端的测试
  • 创建发布包(把node_modules文件夹也打包进去,这样部署的时候就不用依赖NPM了)

自动化测试

自动化测试是构建步骤中最关键的部分。

你的模块必须被单元测试覆盖,你也需要有集成测试来检查各部分能否协同工作。对于这类测试,你可以使用mocha/tap/Jasmine和断言库,如chai.

基于你构建的应用是包含前端的还是只有API,你可以选择不同的端到端测试工具

如果你的程序没有前端页面,只有API,你可以用hippiesupertest做端到端的测试。

当开发包含前端页面的程序时,你还可以对用户界面进行测试。使用Protractor来测试AngularJS程序或者使用Nightwatch。为了确保程序在所有支持的浏览器中运行,需要在Selenium集群上运行端到端测试。也可以使用Sauce Labs或者 Browserstack 服务。

我要不断地强调这件事:没有足够的测试覆盖率,持续集成将导致一系列的生产问题。

创建发布包

如果所有的测试都已经通过,那么就可以从构建打包了。发布包必须包含运行应用程序的每个文件。所以你的成产服务不用再进行重新构建。

一个简单的tar filename.tar *可以做这件事。然后确保文件位置可以被生产服务器访问,这样你才能获取到它。如AWS的S3或者任何的其它存储。

部署

由于我们刚创建的发布包包含程序所有的静态资源,我们只需要进行如下操作:

  • 下载最新发布包
  • 解压到一个新的文件夹
  • 更新symlink,让它指向刚创建的文件夹
  • 重启Node应用

毫无疑问,这些步骤必须自动化,无需任何手动操作。像Ansible、Chef或者Puppet可以帮忙。

回滚

如果发生了错误,早晚会发生。确保有一个回滚的脚本。最快、最简单的方式是将symlink指向到前一个构建并重启node应用。

推荐阅读:

具有可操作性的运行Node.js的建议。

译\Node.js应用的持续部署的更多相关文章

  1. 基于 Node.js 的服务器自动化部署搭建实录

    基于 Node.js 的服务器自动化部署搭建实录 在服务器上安装 Node.js 编写拉取仓库.重启服务器脚本 配置 Github 仓库的 Webhook 设置 配置 Node.js 脚本 其他问题 ...

  2. [译]Node.js - Event Loop

    介绍 在读这篇博客之前,我强列建议先阅读我的前两篇文章: Getting Started With Node.js Node.js - Modules 在这篇文章中,我们将学习 Node.js 中的事 ...

  3. [Node.js] Node.js项目的持续集成

    原文地址:http://www.moye.me/2016/03/03/nodejs_ci_by_jenkins 引子 持续集成 (Continuous Integration,简称CI)是一种软件工程 ...

  4. [译]Node.js面试问与答

    原文: http://blog.risingstack.com/node-js-interview-questions/ 什么是error-first callback? 如何避免无休止的callba ...

  5. [译]Node.js Best Practices

    原文: http://blog.risingstack.com/node-js-best-practices/ 下面的的最佳实践分为代码风格和开发工作流两种. 代码风格 Callback约定 Modu ...

  6. [译]Node.js Interview Questions and Answers (2017 Edition)

    原文 Node.js Interview Questions for 2017 什么是error-first callback? 如何避免无止境的callback? 什么是Promises? 用什么工 ...

  7. node.js express架构安装部署

    安装-g:表示全局安装(必须以安装node.js) npm install -g express-generator 创建一个express架构的项目文件夹express testWebApp 在pa ...

  8. [译]Node.js : Building RESTful APIs using Loopback and MySQL

    国庆后可能就要使用StrongLoop那套东西来做项目了 原文:http://www.javabeat.net/loopback-mysql/ Loopback是什么? Loopback是一个开源的N ...

  9. [译]Node.js Best Practices - Part 2

    原文: https://blog.risingstack.com/node-js-best-practices-part-2/ 统一风格 在大团队开发JS应用, 创建一个风格指南是很有必要的. 推荐看 ...

随机推荐

  1. sql存储过程异常捕获并输出例子还有不输出过程里面判断异常 例子

    编程的异常处理很重要,当然Sql语句中存储过程的异常处理也很重要,明确的异常提示能够快速的找到问题的根源,节省很多时间. 下面,我就以一个插入数据为例来说明Sql Server中的存储过程怎么捕获异常 ...

  2. 解决Office互操作错误"检索COML类工厂中 CLSID为 {xxx}的组件时失败,原因是出现以下错误: 80070005"

    Excel为例(其他如Word也适用)文件数据导入时报出以下错误: 检索COML类工厂中 CLSID为 {00024500-0000-0000-C000-000000000046}的组件时失败,原因是 ...

  3. web前端基础知识jQuery-补

    一.JS正则 1.定义正则表达式 JavaScript种正则表达式有两种定义方式,定义一个匹配类似 <%XXX%> 的字符串: 1)构造函数 var reg=new RegExp('< ...

  4. WebForm 内置对象2

    Session: 与Cookies相比 相同点:每一台电脑访问服务器,都会是独立的一套session,key值都一样,但是内容都是不一样的 以上所有内容,都跟cookies一样 不同点: 1.Sess ...

  5. ZooKeeper的Znode剖析

    在ZooKeeper中,节点也称为znode.由于对于程序员来说,对zk的操作主要是对znode的操作,因此,有必要对znode进行深入的了解. ZooKeeper采用了类似文件系统的的数据模型,其节 ...

  6. [Spring常见问题]java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

    这个问题是因为部署在tomcat下的项目中没有springweb包 但是问题来了,但是我的项目中有呀,maven都引了呀,然后我就懵B啦!看到这个博客我就豁然开朗了:http://my.oschina ...

  7. oracle 11g 服务启动时提示1053错误,服务启动不了,重新配置监听解决问题

    早上发现oracle服务启动不了了,找了很多资料,没找到有用的.通过重新配置监听解决问题.

  8. iOS的数据持久化

    所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) pr ...

  9. SSAS动态添加分区 (转载)

    一.动态分区的好处就不说了,随着时间的推移,不可能一个度量值组都放在一个分区中,处理速度非常慢,如何动态添加分区,如何动态处理分区,成为了很多新手BI工程师一个头痛的问题,废话不多说,分享一下我的经验 ...

  10. JavaScript语言精粹读书笔记 - JavaScript函数

    JavaScript是披着C族语言外衣的LISP,除了词法上与C族语言相似以外,其他几乎没有相似之处. JavaScript 函数: 函数包含一组语句,他们是JavaScript的基础模块单元,用于代 ...