概述

Azure DevOps Server(之前名TFS)是微软公司实现软件研发、测试和部署一体化的全流程解决方案。在近几年的研发过程中,Azure DevOps Server 大幅增强了软件部署过程的自动化功能。对于系统运维人员而言,确保软件的稳定运行,是自己的第一工作目标。但是,在信息技术飞速发展的今天,信息系统的升级变更已经成了家常便饭。每周升级、每天升级、甚至一天升级数次,都已经见怪不怪。

为了提高软件的变更效率和质量,许多运维部门都使用部署脚本,实现系统升级的自动化。在软件升级过程中,为了确保信息系统正常运转,最大程度的降低因为升级导致系统宕机的风险,运维人员首先考虑的是回退(Rollback)方案。即,在系统升级过程中,万一出现由于升级导致的异常状况,为了最快恢复系统的正常运行,回退到部署前的版本,是一个运维人员恢复系统正常的首选方案。

在下面的内容中,我们介绍在使用Azure DevOps Server实现部署过程中,如何应用回退方案。

回退方案

在软件部署过程中,我们可以选择多种回退方案:

1. 基于虚拟机的快照技术

在升级变更之前,为即将发生变更的服务器创建快照,当系统部署失败时,直接将虚拟机退回到创建快照时的状态。

目前Azure DevOps Server支持包括VMware, SCVMM(Hyper-V)等多种虚拟化平台。如果微软原生的技术支持,一般虚拟化平台都提供快照的API,可以将API通过PowerShell、Shell等方式集成到发布流水线中。下图是在Azure DevOps中使用VMware和SCVMM的截图:

图1:Azure DevOps Server流水线中的SCVMM任务

图2:Azure DevOps Server流水线中的vCenter任务

基于虚拟机快照的回退方案,简单粗暴,但是却非常适用。在手动部署过程中,这种方案就是运维人员常用的方式。

但是虚拟机的快照并不是万能的,它存在许多不足,例如快照会消耗大量的磁盘存储;如果是域环境中运行的虚拟机,快照还原可能出现脱域的问题;快照合并的时间较长等问题。在选择使用快照技术作为回退方案时,需要重复考虑快照还原对系统造成的影响。

2. 重新部署上一个版本

在Azure DevOps Server中,重新部署上一个版本,是最为简单和快速的方式。

Azure DevOps Server 最大的特点,是完整地保留了软件研发运维过程中的所有日志、交付物数据,并且保护交付物数据的各种版本,其中就包括部署部署过程中的每一个版本。单本次部署失败时,我们可以从上一次的部署中,选择重新部署按钮,实现一键回退功能。

例如,在下图中,由于四次部署是上一次成功的部署,并且系统运行正常,我选中重新部署,就可以重复运行上一次部署的所有任务,并且在部署过程中,使用上一次部署的升级包、环境变量等数据。

图3:在Azure DevOps Server 中重新部署

如果你熟悉IBM UrbanCode Deploy,会发现Azure DevOps Server的重新部署功能与它的“Replace with Last Deployed”有异曲同工之妙。通过重新部署上一次的版本实现回退,简单快速。但是,问题也显而易见,不一定能够实现系统回退的效果。这种方案只适合独立运行的信息系统。

例如,当系统依赖与第三方系统运行,需要和第三方系统同步升级时,重新部署只能将自己的系统回退到了上一个版本,但是并不能将系统恢复到健康状态,因为此时第三方系统已经完成了升级,可能第三方系统不能兼容你的上一个版本。同样,如果当前版本对应的数据库结构已经完成了升级,重新部署也不能恢复系统的健康状态。

3. 停止自动部署,手动修复问题

程序员和运维工程师不是万能的,相反,这是一群最容易犯错误的人,因为他们实现的大部分需求,都没有可以照搬的方案。都是在开发过程中,不断试错,实现信息系统的增量发展。同样,在部署过程中,每次都存在许多不确定因素。当发现部署问题时,分析原因找到解决方案,并修复问题,将当前环境恢复到健康状态。同事,将解决方案集成到系统源代码或者部署脚本中,作为下一个版本的部署内容。

当然,作为程序员,我们可以提升系统部署智能化,提高部署过程中错误探测和解决的自动化水平,这也是后面要重点介绍的方案。

4. 在流水线中部署回退脚本

在Azure DevOps Server 中,发布流水线由一个一个的任务组合而成。在发布过程中,系统按照流水线中配置的顺序,执行每一个阶段中的任务。当发布流水线中的中的任何任务失败时,对应环境的部署可能会失败。为了让环境恢复正常,我们可以执行一个回滚脚本Shell (on Linux)或PowerShell(on windows)。脚本本身需要具以下要求:

  • 当部署工作流中的任何任务失败时,对环境的部署可能会失败。为了让环境恢复正常,我们将执行一个回滚脚本。即使在另一个任务失败时,脚本本身也会为环境执行脚本。通过Azure DevOps的发布管理,您可以使用PowerShell或shell任务来实现此目的,并将其标记为“始终运行”。这样,无论部署成功或失败,脚本都将始终得到执行。
  • 如果前一个任务失败,则应跳过未标记为“始终运行”的任何任务,但将执行始终运行的任务。根据部署失败的任务对环境进行选择性更改。执行脚本只是任务的一半。为了避免破坏任何不需要的东西,我们需要了解更多内容。首先,我们需要检测是否有故障。如果失败了,那么什么任务失败了。目前,脚本中没有一种方法可以了解这些内容。我们需要在脚本中查询这些版本。幸运的是,Azure DevOps 的市场(https://marketplace.visualstudio.com)中扩展插件“Release Management Utility tasks”(https://marketplace.visualstudio.com/items?itemName=ms-devlabs.utilitytasks),其中包含了一个任务“Powershell to rollback”,这个任务可以协助我们,使回退脚本变得更加简便。如果你想验证下面的脚本,需要将这个扩展安装在你的Azure DevOps Server中。

下面我们来演示如何实现这个功能:

首先,编写回退脚本,并将其推送到代码库中,例如我的回退脚本如下:

echo $env:Release_Tasks

try

{

$jsonobject = ConvertFrom-Json $env:Release_Tasks

}

catch

{

Write-Verbose -Verbose "Error parsing Release_Tasks environment variable"

Write-Verbose -Verbose $Error

}

foreach ($task in $jsonobject | Get-Member -MemberType NoteProperty)

{

$taskproperty = $jsonobject.$($task.Name) | ConvertFrom-Json

echo "task name: $($taskproperty.Name)"

echo "task rank: $($task.Name)"

echo "task status: $($taskproperty.Status)"

echo "Task $($taskproperty.Name) with rank $($task.Name) has status $($taskproperty.Status)"

$task_status=$taskproperty.Status

if($task_status -eq "failed")

{

Write-Warning "This is a error generated in a PowerShell script"

}

}

然后,在发布流水线中添加回退任务。注意需要将其标记为总是运行“即使上一任务已失败,即使已经取消部署”:

最后,我们看一下回退脚本运行的结果:

在上图中,可以看到回退脚本顺利运行,下图是回退脚本的输出:

在上面第4个方案中,我们只是介绍了基于Azure DevOps Server 的回退机制,而具体的回退脚本,需要根据系统部署的内容来定。需要开发人员或者运维人员根据本次变更的具体内容编写脚本。例如文件的变动,则需要编辑将备份文件覆盖回来;如果数据结构的变动,则需要更改数据库。

微软DevOps MVP 张洪君 http://www.cnblogs.com/danzhang

--End--

在Azure DevOps Server(TFS系统)中部署回退/回滚方案(Rollback)的更多相关文章

  1. Azure DevOps Server (TFS)中代码文件换行问题解决方案(Git)

    之前写过一篇博客"探索TFS Git 库文件换行(CRLF)的处理方式",主要是针对TFVC代码库的. 下面这篇文章说明如何在TFS的Git库中处理代码换行的问题. 概述 在Azu ...

  2. 在Azure DevOps Server (TFS 2019) 流水线传递参数

    变量概述 在Azure DevOps Server的流水线中,变量是衔接不同任务和不通代理之间的桥梁,它可以使相对松散.各自独立的任务之间相关影响并共享数据.在流水线中使用变量,可以在各任务之间相互调 ...

  3. Azure DevOps Server (TFS) 代码库Repo管理培训

    Repo是分布式代码库Git中的一个专用词,用于存储和管理开发团队中特定的源代码. 使用Git,可以协调整个团队的代码更改. 即使您只是一个开发人员,版本控制也可以帮助您在修复错误和开发新功能时保持井 ...

  4. 还原Azure DevOps Server (TFS)中误删除的生成流水线

    流水线历史记录 DevOps Server流水线的历史记录有完善的版本日志,用户可以随时回退到修改过程中的任何一个版本,还能比较差异.这个历史记录功能可以和代码库中的版本控制媲美. 图一:生成历史记录 ...

  5. 在Azure DevOps Server (TFS)的流水线中编译和测试Xcode移动应用(iPhone)

    概述 Xcode是开发基于苹果macOS系统的桌面应用和移动应用的主要IDE工具.使用Azure DevOps Server (原名TFS)系统中的pipelines流水线功能,可以方便的集成Xcod ...

  6. 在Azure DevOps Server (TFS)中实现VUE项目的自动打包

    概述 Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据驱动的 web 界面的渐进式框架.由于它在数据绑定.页面展示和使用简单方面有很大的优势,逐渐被越来越多的前端开发团队使用.本文 ...

  7. 集成Azure DevOps Server(TFS) 与微软Teams

    1.概述 Microsoft Teams是Office 365中团队协作的中心.将团队的所有聊天.会议.文件和应用程序放在一个位置.软件开发团队可以在一个专门的协作中心中即时访问他们所需的所有内容,T ...

  8. 在Windows操作系统的文件管理器中集成Azure DevOps Server (TFS)工具菜单

    故事场景 使用过SVN的用户,都知道在Windows的文件夹上点击鼠标右键,就会弹出Tortoise SVN的操作菜单(俗称小乌龟).通过这个功能,用户不需要打开SVN工具,可以直接在Windows的 ...

  9. Azure DevOps Server (TFS) 修改工作项附件大小限制

    1. 问题描述 当上传工作项附件时,系统提示"附件大小限制" 2.解决方案 2.1 默认设置 默认情况下,Azure DevOps Service和Team Foundation ...

随机推荐

  1. Vue proxy

    npm run dev 我们访问的是localhost:8080 config文件夹下的index.js配置文件的dev dev: { env: require('./dev.env'), port: ...

  2. 550 5.7.1 Client does not have permissions to send as this sender

    收发邮件时出现以上这种情况,系统提示550 5.7.1 Client does not have permissions to send as this sender,这是什么原因赞成的呢? 活动目录 ...

  3. TensorFlow Android Camera Demo 使用android studio编译安装和解决Execution failed for task ':buildNativeBazel'报错

    可以参考官网:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#android-stud ...

  4. 初学c# -- 学习笔记(9) 关于SQL2008

    在做一个局域网的类似网盘的学习练习,服务端差不多了,在改bug.用vlc的dll做的全格式视频.音频预览在线播放下载等等. 在做服务端也遇到了一些问题,走了好多弯路. 开始把上传的视频.音频.图像.文 ...

  5. Java中两个线程是否可以同时访问同一个对象的两个不同的synchronized方法?

    不可以!!! 多个线程访问同一个类的synchronized方法时, 都是串行执行的 ! 就算有多个cpu也不例外 ! synchronized方法使用了类java的内置锁, 即锁住的是方法所属对象本 ...

  6. React-router4 第六篇 No Match 404

    https://reacttraining.com/react-router/web/example/no-match react-router-dom 又一个新属性 Switch 在Switch 的 ...

  7. java基础面试(上)

    面向对象的特征 答:抽象.继承.封装.多态 short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗? 答:对于short s1 = 1; s1 ...

  8. CentOS_mini下安装docker 之 yum mount

    --->linux 终端输出太多前面看不到的解决办法:shift+page up --->mount命令[-参数] [设备名称] [挂载点] mkdir /mnt/CentOS mount ...

  9. mysql 的 select into 带来的错误数据问题

    在写存储过程的时候,会有一个被忽视的问题: 比如 select user_name into @user_name from user where id = 1; 会出现 其实没有 id =1 这条数 ...

  10. python基础之Day13

    一.有参装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ...