零宕机布署!让你的数据库轻松实现向后兼容变更

  • 时间:
  • 浏览:0

太多比较复杂布署过程(或多或少这类删除回滚,或多或少数据库回滚几乎不而且)。愿意 们选泽只做应用回滚。采用你这名 方式,即便你有不同的数据库(如SQL和NoSQL),但你的布署过程是一样的。



迁移脚本将数据列last_name重命名为surname

愿意 们有全都有一块儿之处,而且要维护另八个 相同的环境,前要付出双倍的支撑。全都有像Martin Fowler原本的团队倾向更多变通的方式:蓝绿布署的另八个 变体是使用同另八个 数据库,只在网站和域你这名 层做蓝绿切换。

为新版本应用线程准备安装包

假定

应用回滚

版本2一块儿使用last name和surname。



跟v3相比,愿意 们移除了last name而且加进了约束。

写代码,一块儿使用新旧另八个 数据列。现在你的应用版本是2.0.0

愿意 们关闭版本为2.0.0.BAD的应用



异常日志如下:

而且1.0.0版本的应用,真不知道数据列surname的指在,它会抛出异常

回滚应用

代码

应用版本: 2.0.0.BAD

数据库版本: v2bad

而且愿意 们对数据库和应用线程做非向后兼容布署,愿意 们无法使用A/B测试。

本文来自云栖社区战略公司合作 伙伴"DBAplus",原文发布时间:2016-07-01



数据库包括last_name列



应用线程版本:4.0.0

数据库版本:v4



目前清况 是应用线程版本为2.0.0,数据库版本为v2



应用线程将Person数据存储到last_name列:



应用版本: 2.0.0

数据库版本: v2

下面所用到的代码示例,你都也能在GitHub上找到。

部署版本为2.0.0的应用线程,数据存储在last name和surname两列,读取的后后只从last name取值。数据库是v2版本,带有last name和surname两列。surname列是last name的克隆好友。(注意:你这名 列也能有非空约束)

创建另八个 新数据列,命名为surname,并把你的数据库迁移过来。现在你的数据库版本是v2



本文所使用的代码,都也能在Gitbub上下载到。更多的介绍,也能在下面看多。

数据库变更

版本为1.0.0的实例在插入last_name的后后会总是出显异常,而且last_name列而且不指在了

在本节内容中愿意 们将关注数据库变更的并是否方式。

第四步:从数据库移除last name

数据库和应用都而且成功升级,另八个 实例使用版本1.0.0,另八个 使用版本2.0.0.BAD.愿意 会们使用版本为v2bad的数据库

非向后兼容

说明

A/B测试

目前的清况 是愿意 们在生产环境布署了另八个 1.0.0版本的应用,数据库版本为v1。愿意 们想再布署另八个 实例,使用2.0.0版本的应用,将数据库升级到v2.



检查非向后兼容的例子,请运行:

传说中的零宕机布署是个哪此鬼?愿意 把它理解为原本并是否应用线程布署方式:愿意 成功把应用线程的新版本更新到生产环境,而且用户也能宕机的感觉。从用户和公司的高度来看,这是最好的布署方式,而且不仅发布了新的功能,而且也能带来bug。

回滚另八个 版本(都不 太多)通常是愿意 会们能做到的



通过例子也能启动H2 console ,全都有愿意 浏览数据库的清况 (默认的jdbc url 是jdbc:h2:mem:testdb)

将数据从last_name克隆好友到surname。注意,而且你有几滴 的数据,你最好考虑批量迁移的方式!

重要:而且我要基于新/旧列进行或多或少统计查询,请记住,你有另八个 值(而且而且迁移)。这类,你想统计姓氏以A开头的用户数,除非你而且做好了数据迁移(从旧列到新列),而且你在新列上做统计会遇到数据不一致。



通过加进新的数据列和内容克隆好友,愿意 们而且通过向后兼容的方式对数据库做了变更。愿意 们回滚另八个 JAR,一块儿有另八个 老版本的JAR在运行,它后会在运行时挂掉。

无变化

项目:



愿意 们将数据一块儿保存到last_name和surname.愿意 们从last_name读取最新数据。在升级过程中或多或少请求而且会被埋点到还也能更新的实例。

代码而且做了很好的自我解释:愿意 使用SQL定义你的数据库变更。如前要更多了解Spring Boot和Flyway,请参考Spring Boot文档。



愿意 们而且将数据列lastName重命名为surname。

本文将深入介绍怎样才能愿意 的数据库和代码从零停机布署中受益,而且很好地运行。

步骤:

步骤:

愿意 们的项目是另八个 简单的Spring Boot Flyway应用,在你这名 应用中,另八个 Person在数据库里有first_name和last_name另八个 字段。愿意 们想把last_name重命名为surname。

在v2bad 中数据库中而且也能last_name数据列,它而且重命名为surname



步骤:

运行数据库迁移脚本布署运行新版本应用线程

部署版本为4.0.0的应用线程-代码也能任何变化。部署版本为v4数据库,完成最后从last name 到surname的迁移,并删掉last name。并也能加进进前要的约束。

也能怎样才能也能做到?下面是众多方式中的并是否:

从代码变更中分离数据变更

使用模式版本控制工具来管理Spring Boot,有另八个 好处。

脚本

而且surname列的值不为空,从它读取值,而且surname不指在则从last_name读取。愿意 从代码中移除getLastName(),而且而且你把应用从3.0.0回滚到2.0.0,它而且产生空值。

现在,愿意 问个人另八个 问题,而且数据库变更不向后兼容会指在哪此?难道我的版本1后会崩溃不成?事实上,它其实 会。

升级成功,版本为1.0.0的实例和版本为2.0.0的实例一块儿运行,都使用版本为v2的数据库

维护两套生产环境(蓝和绿)

使用脚本加进surname列。

为你的服务布署版本1

说明



假设尝试A/B布署后后,愿意 们前要将应用回滚到1.0.0.而且愿意 们不希望回滚数据库。

第二步: 加进surname



目前的清况 ,应用是3.0.0版本,数据库是v3版本。应用3.0.0不再把数据存到last name列,这原应着,最新的数据是存储在surname列。

为你的服务布署版本2,让版本1和版本2并行

数据库变更

回滚应用到2.0.0版本



采用你这名 技术会有数据库方面的挑战,怪怪的是当软件的新版本前要修改数据库模式的后后。

说明

将应用线程回滚到版本1.0.0。

将数据库迁移到新版本



database仍然使用v2bad

在深入细节后后,愿意 们前要为应用做或多或少假定。主而且让过程变得简单。

在这篇文章中愿意 们使用Flyway做为模式版本控制工具。愿意 们还写了另八个 Spring Boot应用线程,也能为Flyway提供原生支持,然不也能为模式迁移的执行提供应用线程上下文设置。使用Flyway时,愿意 把迁移脚本存储在项目文件夹(默认位置是classpath下的db/migration)。这里有另八个 迁移文件的示例:

A/B测试



愿意 们用last name和surname两列来存储数据。一块儿,从last name读取数据,而且你这名 列数据是最新的。在部署阶段,或多或少需求而且会被也能更新的实例来执行。

太简单了,对不对?而且很不幸,事情并都不 也能简单,愿意 们接下来就探讨你这名 问题。愿意 会们来看一下另外并是否流行的布署方式:蓝绿布署。



检查向后兼容的例子,请运行:

说明

通过URL映射,把所有访问都切换到绿色系统。

你听说过蓝绿布署吗?在云环境下很容易实现。在此前的一篇文章中,愿意 们原本做过高度介绍。快速总结一下,做蓝绿布署要点如下: 



通过或多或少向后兼容的方式,愿意 们成功布署了重命名原本的非向后兼容变更。在此总结一下:

 



步骤:

通过遵守你这名 方式,愿意 做到回滚版本,而后会破坏数据库和应用线程的兼容。

数据迁移和应用线程布署同步,你的布署过程变得简单

重要:记住,新创建的列也能使用NOT NULL,而且你做回滚,老版本应用线程真不知道新的列,后会在插入数据时为它赋值。全都有,而且你加进了你这名 约束,而且你的数据库版本是V2,也能新的数据列的值也能为空,而且违法约束。

提示:作为提醒,假定愿意 们使用V1版本的数据库,它带有列first_name和last_name。愿意 们想把last_name变更为surname.而且愿意 们还有另八个 1.0.0版本的应用还也能使用surname.

此时有或多或少请求会被埋点到使用1.0.0版本的实例



价值形式上,数据库也能变化。执行下面的代码,来实现数据迁移:

布署新实例,应用使用2.0.0,数据库升级到v2

将数据迁移到新版本。



通过加进另八个 新列,并把内容克隆好友过来,愿意 们为数据库配置了向后兼容模式。而且愿意 们回滚到JAR, 一块儿旧的JAR版本也在运行,系统后会奔溃。

数据库变更

布署另八个 新实例,应用线程版本为2.0.0.BAD,将数据库升级到v2bad

而且surname不为null,版本2.0就使用surname。而且为null,就使用last name。

读完以上信息,你而且会问:蓝绿布署和零宕机有哪此关系?

数据库变更

回滚另八个 新版本

部署版本为1.0.0的应用线程和版本为v1的数据库(列名是last name)

说明

应用线程版本:3.0.0

数据库版本: v3

至此,引出了愿意 们今天的主要话题:数据库。愿意 会们再回顾一下这句话:

模式版本

数据库问题

而且版本运行很完美,把版本1停掉



在当前环境中愿意 们布署了另八个 版本为1.0.0的应用线程和另八个 版本为v1的数据库。愿意 们要布署另外另八个 实例使用版本为2.0.0的应用线程,而且将数据库升级到v2bad。



代码变更

步骤:

其实 零宕机/蓝绿布署很强大,而且出于安全考虑,公司仍然顷向于以下方式:

愿意 们不前要做数据库回滚

通过蓝绿布署,发布新功能变得很轻松,不再担心把bug引入到生产系统。而且愿意 通过路由映射很方便地回滚到前另八个 版本,就像“拨动开关”一样简单。

代码变更



这是愿意 们要使用的应用线程初始清况



数据库带有另八个 数据列last_name

1.0.0不使用数据列surname,2.0.0使用。愿意 们彼此也能交互,后会抛出异常。

你做到了!

关闭运行中的应用

提示:忠告,比较复杂的流程也能为你节省全都有钱(公司人太多,也能节省的钱太多)!

脚本执行的日志:

而且你的应用是无清况 的,不前要使用数据库来存储任何数据,那你现在就也能做到零宕机布署。但不幸的是,大每段软件都前要把数据存到某个地方。这而且为哪此在做任何数据库模式变更时,你都不 再三考虑。在愿意 们探讨数据库模式变更细节前,愿意 会们先关注模式版本。

代码变更:

零宕机布署

愿意 们只回滚到所前要的版本。而且当前版本指在bug,而且不容易修复,愿意 们希望也能回到上另八个 稳定版本。愿意 们假定上另八个 稳定版本而且上另八个 版本。为多个布署维护代码和数据库兼容是困难且昂贵的。

代码变更

1.0.0不使用数据列surname,全都有回滚成功。

版本为2.0.0.BAD的实例也能正常运行

提示:为了提高可读性,愿意 们在文章中将只展示代码的新增内容。

本文将深入探讨怎样才能外理数据库兼容性以及布署过程相关的或多或少问题。而且你也能做或多或少准备工作就去尝试本文介绍的布署方式,我将无法预知你的应用会指在哪此。接下来,愿意 们将透过应用线程生命周期的每一步骤介绍零宕机方案。愿意 们的应用线程最终要达到的效果是在另八个 不支持向后兼容的数据库上实现向后兼容变更。

向后兼容

任何测试和变更都不 绿色系统中进行;

而且你正在使用Spring Boot Flyway,通过这两步也能启动2.0.0版本的应用。而且你是手动运行数据库版本控制工具,你前要在另八个 独立的线程中操作(先手动升级数据库,再布署新应用)。

而且也能做好准备,太多用第一方式做零宕机布署,愿意 们会给出警告。第二种方式,愿意 们会提供或多或少零宕机向后兼容的布署建议。

步骤:

代码变更

使用向后兼容方式重命名数据列



当前变更不允许愿意 们一块儿运行另八个 实例(新旧另八个 版本)。全都有零宕机布署是难以达到的(根据愿意 们的假定,这实际上是不而且的)。

回滚应用



而且应用3.0.0不使用last name,在从数据库移除你这名 列后,而且愿意 们回滚到版本3.0.0,后会指在崩溃清况 。

重要:你前要移除getLastname()方式,而且在3.0.0版本中的代码中真不知道数据列last_name。这原应着默认会把它的值设置为空。你可是我我能保留该方式,但要加进判空检查,而且最好的方案是getSurname()在逻辑上保障也能空值。



克隆好友代码仓库后,愿意 看多如下文件价值形式:



所有的例子都克隆好友于Spring Boot Sample Flyway项目。

使用非向后兼容方式重命名数据列

数据变更

灾难性故障,无法回滚

第一步:初始化环境

译者:张万程

第三步:从代码中移除last name

 

警告:记住,太多为新加列设置非空约束。而且JAR回滚时旧版本真不知道新加列,会自动设置空值。而且有非空约束,旧版本应用会崩溃。

 

2.0.0将数据保存到新旧另八个 数据列,全都有是向后兼容的



在你这名 例子里愿意 们也能看多八个迁移脚本,而且后后也能执行过,在应用启动时而且顺序依次执行。我要打开另八个 文件(V1__init.sql)看一下。



假设要修改列名,愿意 们来看一下下面的例子:



警告:下面的例子是故意原本做的,它会崩溃。愿意 们用它来展示数据库兼容问题。

而且愿意 们对数据库和应用做非向后兼容变更,愿意 们无法回滚到前另八个 版本。



愿意 运行脚原本执行并是否场景:数据库向后兼容和非向后兼容。

执行非向后兼容变更是愿意 们总是遇到的清况 。愿意 们而且证实,而且不做些额外工作,无法通过简单的数据库迁移做到零宕机布署。本节内容将通过三次应用线程布署和数据库迁移达到愿意 们期望的效果,而且一块儿做到向后兼容。

通过URL映射,只让浅绿色系统对外提供服务;

部署版本为3.0.0应用线程,数据只存储在surname列,读取时从surname列取值。对于数据库,最后从last name迁移到surname。对于last name列,not null限制要撤销。数据库现在是v3版本。



应用版本: 1.0.0

数据库版本: v1