组件自治性与flyway best practice

简介: 组件自治性,从技术上就对组件数据自包含提出了要求。通过Flyway支持数据版本管理,满足数据自包含的要求

背景

组件自治性的要求

云巧对组件的要求是可独立运行。 每个组件都是自包含的,在限界上下文中实现单个业务功能。 限界上下文是业务内的自然划分。

从技术层面,组件中的微服务就需要满足数据自包含的要求,即通过组件的代码版本管理实现数据的版本管理。

数据自包含的优点

数据自包含具有以下优点:

  • 敏捷性:由于微服务是独立部署的,因此我们可以更轻松地管理 bug 修复和功能发布。 无需重新部署整个应用程序即可更新服务,出现问题时可回滚更新。 在很多传统应用程序中,如果在应用程序的一个部件中发现 bug,它会阻止整个发布流程。 新功能可能会被搁置,要等到 bug 修补程序后才能进行集成、测试和发布。
  • 小型研发团队:微服务应该足够小,单个功能团队就能构建、测试和部署。 即使团队规模不大,也能大幅提升敏捷性。 而由于沟通效率更慢、管理开销更高且敏捷性更低,大型团队的工作效率往往更低。
  • 小型代码库:在整体式应用程序,代码依赖项往往会随着时间的推移而变得混杂。 要在多个位置更改代码才能添加新功能。 如果不共享代码或数据存储,则微服务体系结构可将依赖项减到最少,使新功能的添加变得更容易。
  • 数据隔离:执行架构更新要容易得多,因为只会影响单个微服务。 在整体应用程序中,更新架构可能极具挑战性,因为应用程序的不同部分可能都要获取相同的数据,对架构进行任何更改都会带来风险。
  • 单元测试友好:通过代码库即可支持单元测试的数据用例管理。

挑战

数据自包含的优势并非没有代价。 下面是一些在使用数据自包含后可能会遇到的挑战:

  • 管理规范:需要在研发团队内制定规范,保持统一的版本管理标准
  • 数据完整性:通常建议采用最终一致性。
  • 版本管理:多个服务可在任意给定时间更新,因此,若不精心设计可能会遇到向后或向前兼容性问题。
  • 研发人员能力:评估团队是否具有所需的技能和经验。


敏捷交付迭代对分支和数据版本管理的要求

项目在推行敏捷交付,迭代周期不一定严格按照121模式。在2周的迭代周期内,分为4个小组。哪个小组完成了需求就先上线。

分支模式可以支持敏捷交付形式。

例如,在2020/12/1的时候定好了12/15是一个迭代周期,首先从master一个release/20201215。

在12/8的时候有一组已经完成需求1001可以发布了。那么就从master拉出一个release/20201208分支,将feature/1001合并到release/20201208分支,进行回归测试后发布release/20201208。发布完成后将release/20201208合并到master和release/20201215。


flyway的工作模式

Flyway是Spring官方推荐的数据自治和版本管理的工具。

Flyway支持对数据库进行升级,从任意一个版本升级到最新的版本。但是升级的依据是用户自己编写的sql脚本,用户自己决定每一个版本的升级内容。

Flyway不限定脚本里面的内容,但是对脚本文件的名称有一定的要求:

版本号可以使用小版本,如V1.1。

具体要求:

  • 版本号和版本描述之间,使用两个下划线分隔。
  • 版本描述之间,使用一个下划线分隔单词。
  • 版本号唯一:不允许多个脚本文件有相同的版本号。

使用Flyway升级,flyway会自动创建一张历史记录表:flyway_schema_history。

这张表记录了每一次升级的记录,包括已经执行了哪些脚本,脚本的文件名,内容校验和,执行的时间和结果:

flyway在升级数据库的时候,会检查已经执行过的版本对应的脚本是否发生变化,包括脚本文件名,以及脚本内容。如果flyway检测到发生了变化,则抛出错误,并终止升级。

如果已经执行过的脚本没有发生变化,flyway会跳过这些脚本,依次执行后续版本的脚本,并在记录表中插入对应的升级记录。

所以,flyway总是幂等的,而且可以支持跨版本的升级。


交付项目中flyway的使用

项目中使用了flyway,所有环境的数据库脚本都通过flyway自动发布。

flyway的命名规范如下:

按照V+大版本号数字+.发布日期+.执行顺序(3位数字)+__操作(init/update/add/alter/modify)+_操作对象+_脚本创建人拼音.sql的格式

范例:V1.20211105.003__update_menu_wss.sql

范例中,flyway的版本号位V1.20211105.003。这个版本号必须是全局唯一的。


按照规范,交付项目中不允许直接操作任何环境的数据库,包括日常/测试/生产。所有的数据库变更都必须通过flyway来实施。这个方案的好处是确保了所有的上线脚本都能通过版本控制管理起来。


实践中遇到的问题

项目在敏捷交付过程中,对于flyway的使用遇到了两个问题:

  • 同一个迭代的脚本里可能会存在顺序依赖。如果被依赖的脚本所在迭代晚于依赖的脚本所在迭代上线,那么上线的时候会发生错误
  • 如果每个人都在自己的分支里提交脚本,可能版本号会有冲突,导致flyway执行失败。
  • 考虑统一建立一个分支,所有的脚本只通过这个分支来提交


对于脚本顺序依赖,常见的情况为:脚本A中新增表/列/数据,脚本B依赖于脚本A中所建立的表/列/数据


解决思路

版本号冲突的问题比较好解。可以在每个迭代分支建立后,建立一个对应的分支。例如:feature/20201215_db。在项目组内约定这个分支只提交脚本。每位开发在提交完脚本后,将这个feature分支合并到自己的个人分支,以确保脚本最终也会合并到release分支上。


脚本顺序依赖的问题,需要项目组上贯彻3点:

  • 平时功能测试只用日常环境发布,只在确定了上线前才用测试环境发布
  • 每个脚本可重复执行
  • 同一个迭代内的脚本之间禁止互相依赖


只在上线前才用测试环境,主要是用于验证上线脚本。这是第一重保险。

每个脚本可重复执行+同一个迭代内的脚本之间禁止互相依赖,这是第二重保险。


脚本可重复执行

要做到脚本可重复执行,可以参见这篇:https://blog.csdn.net/a2234150293/article/details/101546811

摘抄如下(有少量修正):

数据库脚本一般分为:

1.DDL(数据定义语言)操作对象是表,包含:Create、Drop、Alter

2.DML(数据操控语言)操作对象是数据,包含:Insert、Delete、Update

3.DCL(数据控制语言)操作对象是权限、用户,Grant、Revoke

DDL

Create

CREATETABLE IF NOT EXISTS `USER` (  `ID` int(11)NOTNULL AUTO_INCREMENT,  `MOBILE` varchar(20) DEFAULT NULL COMMENT '手机',  `NAME` varchar(20) DEFAULT NULL COMMENT '用户名',  `PASSWORD` varchar(20) DEFAULT NULL COMMENT '密码',  `IS_ENABLE` int(2) DEFAULT NULL COMMENT '是否有效 1有效 0无效',  `CREATE_TIME` datetime DEFAULT NULL,  `UPDATE_TIME` timestampNULL DEFAULT NULLONUPDATE CURRENT_TIMESTAMP,  `CREATE_BY` varchar(20)NOTNULL DEFAULT 'admin' COMMENT '创建者,记录创建者信息',  `LAST_UPDATE_BY` varchar(20)NOTNULL DEFAULT 'admin' COMMENT '修改者,记录修改者信息',  PRIMARY KEY (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';


Drop

DROPTABLE IF EXISTS `USER`;

Alter

CREATE PROCEDURE ADD_USER_ADDRESS()BEGIN    IF NOT EXISTS (SELECT*FROM information_schema.COLUMNSWHERE table_schema ='wen'AND table_name ='USER'AND column_name ='ADDRESS') THEN
ALTERTABLE `USER`
  ADD COLUMN `ADDRESS` varchar(20)NULL COMMENT '用户住址' AFTER `UPDATE_TIME`; END IF;END;CALL ADD_USER_ADDRESS;DROP PROCEDURE ADD_USER_ADDRESS;

DML

Insert

DELETEFROM USER WHERE ID =1;INSERTINTO `wen`.`USER` (`ID`, `MOBILE`, `NAME`, `PASSWORD`, `IS_DELETED`, `CREATE_TIME`, `LAST_UPDATE_TIME`, `CREATE_BY`, `LAST_UPDATE_BY`)VALUES('1','18888888888','测试用户','123456','2021-09-27 15:17:37',NULL,'admin','admin');

Delete

数据库一般不建议也不允许进行物理删除。

真的需要物理删除,参考下文update先进行备份。

Update

/*备份表与数据*/DROPTABLE IF EXISTS `USER_20210927`;/*第一次运行保留,后面删除*/CREATETABLE USER_20210927 LIKE USER;INSERTINTO USER_20210927 SELECT*FROM USER;/*软删除2021-09-23前数据*/UPDATE USER
SET IS_ENABLE =0WHERE IS_ENABLE =1AND CREATE_TIME <'2021-09-27 00:00:00'
相关文章
|
监控 Java Linux
开源流程引擎Camunda
开源流程引擎Camunda
|
3月前
|
SQL Java 数据库连接
数据库迁移不再难:Flyway 与 Liquibase 大比拼,哪个才是你的真命天子?
【9月更文挑战第3天】数据库迁移在软件开发中至关重要,尤其在使用 ORM 框架如 Hibernate 时。为确保部署时能顺利应用最新的数据库变更,开发者常使用自动化工具。Flyway 和 Liquibase 是当前流行的两种选择,均能有效管理数据库版本控制。Flyway 采用 SQL 脚本表示变更,简单易用;Liquibase 支持多种脚本格式,功能更强大,适合复杂项目。本文将对比这两种工具的特点,并通过示例展示各自的优缺点,帮助开发者根据项目需求做出合适的选择。
820 1
|
4月前
|
存储 测试技术 数据库
Entity Framework Core Migrations 超厉害!轻松实现数据库版本控制,让你的开发更顺畅!
【8月更文挑战第31天】数据库的演变是软件开发中不可或缺的部分。随着应用发展,数据库需不断调整以适应新功能。Entity Framework Core Migrations 作为数据库的守护者,提供强大的版本控制手段,确保不同环境下的数据库一致性。通过创建和管理迁移脚本,开发者可以有序地管理数据库变更,避免混乱和数据丢失。安装并配置好 EF Core 后,可以通过命令行工具轻松创建、应用及回滚迁移,如 `dotnet ef migrations add InitialMigration` 和 `dotnet ef database update`。
58 0
|
7月前
|
SQL Oracle 关系型数据库
flyway 的优缺点
Flyway 是一个开源的数据库迁移工具,用于在应用程序的开发过程中管理数据库的变更。以下是 Flyway 的一些优缺点: 优点: 1. **简单易用:** Flyway 的设计目标之一是简单易用,它采用约定优于配置的原则,使得开发人员可以快速上手并集成到他们的项目中。 2. **无依赖:** Flyway 是一个独立的数据库迁移工具,不需要依赖其他的库或服务。它可以轻松集成到各种项目中,不受特定框架或技术的限制。 3. **支持多种数据库:** Flyway 支持多种数据库系统,包括常见的关系型数据库(如MySQL、PostgreSQL、Oracle、SQL Server等),这使得
346 0
|
SQL 缓存 Java
Ruoyi集成flyway后启动报错的解决方法
本文简单介绍了ruoyi系统以及flyway数据库版本控制技术。并说明了如何在ruiyi中集成flyway组件。重点阐述了集成flyway的过程中会遇到的问题以及针对这个问题的三种不同的解决方案。
730 0
Ruoyi集成flyway后启动报错的解决方法
|
SQL Java 关系型数据库
数据库版本管理工具 Flyway 简单使用
如何快速上手使用数据版本管理工具 Flyway
479 0
数据库版本管理工具 Flyway 简单使用
|
存储 应用服务中间件 开发者
Drools规则引擎Business Central Workbench版本变更
Drools规则引擎Business Central Workbench版本变更
481 0
|
Java 关系型数据库 MySQL
atomikos多数据源配置-在工作流(activiti)分库时的事务管理实战
近期开发一个工作流(activiti)项目,为了方便扩展,想把activiti的数据库和业务数据库分离。那么在项目里面需要针对两个数据库分别定义数据源。 注意: 下文的atomikos只能解决工作流项目在单应用单服务节点时候的事务问题。 微服务架构下需要采用别的分布式管理框架,比如使用seata,那么此时需要还原成 下文中最基本的`配置多个数据源`的方式
1483 0