65.9K
CodeProject 正在变化。 阅读更多。
Home

来自与 Orckestra 的 DevOps Hackfest 的经验教训

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2016年9月29日

CPOL

12分钟阅读

viewsIcon

22929

Orckestra 与微软合作举办了一场为期一周的 Hackfest。在此期间,我们讨论了可以改进其软件交付流程的各种 DevOps 实践。

Orckestra 与微软合作举办了一场为期一周的 Hackfest。在此期间,我们讨论了可以改进其软件交付流程的各种 DevOps 实践,例如

  • 自动化负载测试
  • 作为持续集成一部分的自动化功能测试
  • 用户遥测
  • 微服务和容器化

Orckestra 的核心黑客团队成员包括:

  • Maxime Beaudry - 高级开发人员
  • Nicolas Rose - 软件工程总监
  • Stephane Lapointe - 云解决方案架构师和微软 Azure MVP
  • Stephane Larocque - 高级开发人员和团队负责人
  • Guillaume Salles - UI 架构师
  • Simon Michaud - 自动化团队负责人
  • Guillaume Raymond - 解决方案架构师
  • Michael Bouchard - 高级开发人员
  • Phillipe Ouimet - 平台架构师
  • Marion Roche - 高级开发人员
  • Nicolas Gauthier - 高级开发人员和团队负责人
  • Christian Rousseau - 主管基础设施架构师
  • Mélanie Gillet - 高级开发人员和团队负责人
  • Julie Gueho - 产品负责人

微软的技术布道师也加入了他们:

客户简介

Orckestra 成立于 2006 年,是 .NET 电子商务解决方案和服务的领先提供商。公司总部位于加拿大蒙特利尔,并在欧洲和美国设有办事处。

在此次 Hackfest 中,我们重点关注了他们的主要产品 Orckestra Commerce Cloud (OCC),这是一个统一的商务平台,使零售商能够为在线、移动和实体店的客户创造无缝的购物体验。

架构概览

目前,OCC 是一个在 Azure (IaaS) 的多个虚拟机上运行的单一系统。每个客户都有其专用的 OCC 基础设施,虚拟机的数量可能根据客户的大小而有所不同。

问题陈述

我们用第一天半的时间建立了一个从概念到生产的当前交付流程的价值流图 (VSM)。这项活动在团队之间产生了热烈的讨论,并让每个人都能看到全局——而不仅仅是他们流程中的一部分。

正如价值流图所示,实际上有两个团队按顺序工作来交付最终产品。
第一个团队 (产品核心团队) 负责核心平台 (OCC) 和所有客户共有的功能。其流程由上图的顶部行描述。

完成后,另一个团队 (产品实施团队) 接收 OCC 包并添加特定于客户的功能。然后将包含两个团队工作的软件包发布给最终客户。这些流程在 VSM 图的底部行中进行了描述。

这两组流程形成了一个单一的价值流,而不是两个,因为只有当平台实际交付给客户时,价值才算交付。

价值流是设计、生产和将商品或服务交付给客户所需的活动序列。[…]
价值流映射 - Karen Martin & Mike Osterling

为了支持更快的价值交付,Orckestra 已经实施了许多 DevOps 实践,其中包括:

  • 持续集成 (CI): 在任何分支上的提交都会触发 Visual Studio Team Services (VSTS) 的新构建,并运行单元测试。
  • 集成测试: CI 通过后,将触发新的发布。此发布将在解决方案上运行集成测试。由于这是一个漫长的过程 (约一小时),多个提交会被分组到一次发布中。
  • 代码审查: 功能是在单独的功能分支上开发的。要合并回开发分支,必须在 VSTS 中打开一个拉取请求,并获得至少另外两个人的批准 (技术和业务)。
  • 自动化部署: 每天晚上 (或按需),Jenkins 会使用最新可用版本部署集成和 QA 环境。
  • Hackfest 的目的是探索新的改进机会,并制定一个执行计划,在接下来的几个月内实施这些改进。

Hackfest 目标

我们为为期四天的 Hackfest 达成了两个目标:

在短期到中期目标上,改进当前流程的交付周期。
当前流程无法在几天内改变,因此需要找到改进方法。在价值流映射期间,我们提出了许多关于如何优化它的建议,并同意就以下主题进行工作:

  • 负载测试: 目前负载测试有太多手动步骤。我们着手自动化和简化它。
  • 功能测试: 虽然前端的某些部分已经有功能测试,但自动化是缺失的。我们希望改变这一点,使其成为持续集成的一部分。
  • 用户遥测: 这是 Orckestra 已经设想但尚未实施的内容。用户遥测允许团队了解用户在生产环境中如何使用 (或不使用) 一个功能。这一点非常重要,尤其是在处理长交付周期时,因为它有助于更有效地确定工作优先级。

探索新流程
我们还决定探索让平台交付更小的更新,这些更新可以直接部署到所有客户环境的生产环境中,而无需为每个环境进行手动干预。Orckestra 目前正在实施的选择选项包括:

  • 微服务架构: OCC 如何拆分成更小、独立的模块?
  • 容器: 除其他优点外,容器还可以实现更轻松的部署以及从开发到生产的一致环境。

映射完成后,我们将其移到一个每个人都可以看到和讨论的地方。

如果您想以高清查看 VSM,请查看资源部分。

解决方案、步骤和交付

负载测试

Orckestra 过去曾使用 Visual Studio 的 Test Controllers 和 Test Agents 在部署在 Azure 上的多个虚拟机上运行负载测试。虽然这些负载测试能够达到目的,但还需要更有效的自动化负载测试。

为此,QA 团队在 Hackfest 开始前几周就开始重新思考这个环节。他们决定研究 LoadImpact.com 的云解决方案,首先生成他们前端部分和应用程序 API 部分的 Web 测试。

在我们的 Hackfest 期间,QA 团队花时间在他们的 LoadImpact.com 订阅中设置了一些场景,同时我们主动开发了一个 VSTS 扩展,以便他们可以随时在他们的构建或发布管道中自动启动一些测试场景。通过这种方法,我们向 Orckestra 证明,在他们看来,一切都可以自动化,这要归功于一些“技巧”,例如本例中的一个扩展。

因此,我们在 GitHub 上启动了 这个名为 loadimpact-vsts-extension 的项目

这个想法很简单:通过构建或发布步骤,随时通过 LoadImpact.com API 启动已设置的场景。

目前,这个扩展非常简单,但它有助于 Orckestra 启动一些递归测试,例如:

  • 基本的 API 调用,以检查应用程序的重要部分是否以定义的正确 SLA 进行响应。
  • 基本的 Web 调用,以检查应用程序的所有组件是否正在响应。

我们使用了 (TypeScript, Gulp, NPM…)。

负载测试现在直接集成到他们的管道中,这有助于 Orckestra 进行更有效的测试,并确保测试每次都被运行,而不是手动触发。

这是从 VSTS 启动的测试“GetGuestCart”的示例。

当 Load Impact 完成测试时,Orckestra 会收到 Slack 通知。

我们还开始在 OCC 中实现 Application Insights 功能来跟踪用户交互 (请参阅下一节)。未来,Orckestra 将把负载测试数据与用户遥测数据相关联,以获得更深入的结果,并调整其负载场景以预测规模。

功能 UI 测试

然后,我们对 Orckestra 的某个前端应用程序中已有的功能测试,使用了相同的方法,使其成为持续集成管道的一部分。更快的反馈总是更好的。

这些测试是用 Node.js 编写的,并使用 Nightwatch.js 来与 UI 交互。在后台,Nightwatch.js 使用 Selenium)。下面是一个简单的 Nightwatch 测试示例:

describe('Demo test for Mocha', function() {

  describe('with Nightwatch', function() {

    //Removed some code for clarity

    it('uses BDD to run a simple test', function(client) {
      client
        .url('http://google.com')
        .expect.element('body').to.be.present.before(1000);

      client.setValue('input[type=text]', ['nightwatch', client.Keys.ENTER])
        .pause(1000)
        .assert.containsText('#main', 'Night Watch');
    });
  });
});

我们加载一个网页 (本例中为 google.com),检查页面是否正确显示 (body 存在),输入搜索词,最后检查结果是否包含我们预期的结果。然后 Nightwatch 会输出一个 JUnit 测试报告,可以被 VSTS 导入。

目前,我们决定使用一个安装了 Chrome 的自定义构建代理。但是,可以使用 PhantomJS 或类似的库来代替实际浏览器,使这些测试可以在托管代理上运行。

用户遥测

为了更好地理解和比较不同功能的价值,我们决定实施一些用户遥测,以确定哪些功能被使用,哪些没有。产品管理团队将获得具体的数据,以帮助他们通过了解功能的使用方式来验证不同功能的优先级。

我们的目标是能够监控一个用 JavaScript (Angular.js) 构建的前端应用程序的不同功能的用法,以此作为开始。该应用程序还使用了 Redux,这是一个作为 MVC 模式替代品的库,有助于编写行为一致的应用程序。在 Redux 中,每个事件 (例如,用户单击按钮、服务器响应) 都被称为一个 action,并通过一个纯 JavaScript 对象进行描述。每个 action 都有一个 type,并且可能具有描述事件的其他属性。例如,描述用户添加评论的 action 可能如下所示:

{
  type: 'ADD_COMMENT',
  text: 'This is a comment'
}

然后调度此 action 以允许系统做出相应反应 (例如,更新评论数量的计数器)。Redux 的一个有趣的特性是,每个 action 都会首先通过一个称为 dispatcher 的组件。这意味着我们可以向 dispatcher 添加一个自定义钩子来监控所有通过系统的 action。这些类型的钩子被称为 middleware

我们决定构建一个自定义中间件,将 action 发送到 Azure 上的 Application Insights。这将允许对功能进行精确的使用情况监控。您可以在 GitHub 上找到已完成且可重复使用的中间件。

首先,我们需要在 Azure 上创建一个 Application Insights 实例,从门户获取 JavaScript 代码片段,并将其添加到我们的应用程序中。然后,我们将自定义中间件插入到应用程序中。之后,唯一剩下的就是定义我们想要跟踪哪些 action。

我们可以记录发生的每个 action,但过多的日志记录就像没有日志记录一样,因为它使得查找有意义的信息变得更加困难 (请参阅 Jeff Atwood 关于此主题的帖子)。

要将一个 action 标记为感兴趣的,我们只需附加该对象:

{
  type: 'ADD_COMMENT',
  text: 'This is a comment',
  meta: {
    appInsights: { trackPayload: true}
  }
}

我们可以看到 Application Insights 正确接收我们的 action。

一个好的做法可能是,在推出新功能之前定义我们的期望。例如:“我们期望 10% 的用户每天发布一次评论 (我们的新功能)。” 然后,通过 Application Insights Analytics,我们可以创建自定义查询,例如在其中发生“ADD_COMMENT”事件的会话的百分比。通过将我们的期望与现实进行比较,我们可以决定下一步的方向。

展望未来:微服务和容器

黑客团队的一部分花了一些时间研究如何通过重新思考整个发布流程来更显著地改进价值流。该项目将运行很长时间,我们在 Hackfest 期间只触及了表面。

目前,应用程序是按照单一价值流构建的。未来,该流将分成两个更小的流:

  • 平台 (OCC) 的价值流:核心系统的任何非破坏性更新都应该能够非常轻松地独立发布。
  • 另一个用于交付每个客户的定制功能的价值流。

由于当前的 OCC 平台随着时间的推移已经发展到支持许多用例,因此微服务是下一步将复杂性分解为一组更小的可部署模块的正确选择。Orckestra 现在正在将新服务作为微服务交付,并随着时间的推移将其一些现有服务转换为微服务,以便它们也可以单独发布。我们还花了一些时间研究这些独立组件的容器化。事实上,这将通过解决几个痛点来进一步缩短交付周期:

  • 确保集成测试在生产环境般的运行。
  • 更快的部署。只需要重新部署更新的组件的映像。
  • 更轻松的生产环境扩展。使用 Docker Swarm 等工具,扩展几乎可以无痛地完成 (对于无状态组件)。
  • 集成和 QA 环境部署的更大灵活性。环境的配置和取消配置成为一个极其快速的过程。

当然,存在权衡。虽然微服务提供了许多优势,但它们也很复杂。依赖项更难正确管理,破坏性更改变得难以处理。总的来说,微服务在测试、部署和 API 设计方面需要更多的纪律。

该平台目前运行在 .NET 4.5.3 上,因此容器需要使用 Windows Server Core 作为基础映像,因为 Nano 只支持 .NET Core。由于 Docker 的缓存,映像的大小 (Server Core 映像约为 9 GB) 不应该成为太大问题。

然后,可以使用 Docker Swarm 来协调不同的容器。DC/OS 在不久的将来也应该支持 Windows 容器。但这另当别论。

结论

考虑到流程的复杂性和涉及的人员数量,价值流映射是一项具有挑战性的活动,但它帮助团队看到了全局,并理解了在他们日常工作之外真正发生的事情。

在这次 Hackfest 期间,我们讨论了许多关于如何改进流程的非常有趣的创意,有些比其他的更可行。但最重要的是,整个团队认识到持续改进的价值,并且他们致力于并愿意为此付出巨大的努力。自 Hackfest 以来,团队已经取得了重大的负载测试自动化改进,并且他们即将完成第一个基于微服务的服务,未来还会有更多。

资源

© . All rights reserved.