国际化多版本环境如何用 Zadig + Migrate 统一数据和代码变更
作者:楚乔
路特斯(Lotus)运维开发工程师
在国际化多机房部署的场景下,国内生产部署的是最新版本,国外部署的是落后 1 个甚至 N 个迭代的版本。当业务需要在国外升级到指定中间版本时,当前只能靠运维根据现有版本和指定中间版本之间的 N 次发布文档,挨个汇总 SQL 变更内容,非常费时费力,且容易出错。
因为想要自动化整个数据变更流程,所以选用社区比较有名的 go-migrate 和比较主流的数据库变更工具 flyway 做相应的尝试,并最终对 go-migrate 做二次开发来实现上述能力。
下面分享我们对这两个方案的验证过程及具体实践,以供社区同学参考。
方案描述
以数据库为单位,建立单独 GitLab 项目管理数据库所有的 SQL 变更,变更范围以版本为单位。
工具选型
工具 | go-migrate [1] | flyway [2] |
Github stars | 9.6K | 6.7K |
功能 | 类似 python flask框架 migrate 功能 | undo 等重要功能需要买企业版 版本对比 [3] |
复杂度 | 适中 | 较高 |
源码 | 完全开源 | 有开源版和企业版 |
多个微服务共用一个数据库 | 不支持,可简单二开支持 | 不支持,二开复杂度较高 |
下面主要介绍
这两个工具的最小 demo 供大家参考。
flyway
前置准备
安装 flyway
从官网下载 flyway cli 工具 [4] 并安装,选择适合自己电脑操作系统和芯片架构的二进制文件。
准备数据库
使用 Datagrip 工具创建测试数据库用于 demo。
1 create database flyway_test default character set utf8mb4 collate utf8mb4_unicode_ci;
准备项目
创建 spring boot 测试项目 mysql-test ,pom.xml 文件中增加 flyway 依赖。
1<dependencies>
2 <dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter-data-jpa</artifactId>
5 </dependency>
6 <dependency>
7 <groupId>org.flywaydb</groupId>
8 <artifactId>flyway-core</artifactId>
9 <version>6.0.8</version>
10 </dependency>
11 <dependency>
12 <groupId>mysql</groupId>
13 <artifactId>mysql-connector-java</artifactId>
14 <scope>runtime</scope>
15 </dependency>
16</dependencies>
1718<build>
19 <plugins>
20 <!--flyway-->
21 <plugin>
22 <groupId>org.flywaydb</groupId>
23 <artifactId>flyway-maven-plugin</artifactId>
24 <version>6.0.8</version>
25 <!--配置属性-->
26 <configuration>
27 <user>root</user>
28 <password>root</password>
29 <url>jdbc:mysql://127.0.0.1:3306/flyway_test</url>
30 </configuration>
31 </plugin>
32 </plugins>
33</build>
application.yml 文件中增加数据源配置
1spring:
2 datasource:
3 driverClassName: com.mysql.cj.jdbc.Driver
4 url: jdbc:mysql://localhost:3306/flyway_test?serverTimezone=UTC&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
5 username: root
6 password: root
7 # flyway
8 flyway:
9 baseline-on-migrate: true
10 locations: classpath:/db/migration
11 check-location: true
12 enabled: true
13 #jpa
14 jpa:
15 database: MYSQL
16 show-sql: true
17 hibernate:
18 ddl-auto: none
增加 SQL 变更文件,注意目录为 src/main/resources/db/migration
sql 文件命名规则
首位大写字母V ,固定格式;
后面跟上版本号,版本号为数字、点、或者下划线组成;
版本号后跟上__(注意:这里是两位下划线),固定格式;
__后跟上文件描述,无限制,最好做到见文知意,如:V2_creatTableStudent.sql
本地验证
本地执行以下命令
1 # 本机 mac 执行
2 mvn clean package -U -Dmaven.test.skip=true -e
3 ./lotus.sh
45 2022-08-30 10:15:25.347 INFO TID: N/A 98445 --- [ main][] o.f.core.internal.command.DbMigrate : Current version of schema `flyway_test`: << Empty Schema >>
6 2022-08-30 10:15:25.358 INFO TID: N/A 98445 --- [ main][] o.f.core.internal.command.DbMigrate : Migrating schema `flyway_test` to version 1 - init
7 2022-08-30 10:15:25.567 INFO TID: N/A 98445 --- [ main][] o.f.core.internal.command.DbMigrate : Migrating schema `flyway_test` to version 2 - create route
8 2022-08-30 10:15:25.703 INFO TID: N/A 98445 --- [ main][] o.f.core.internal.command.DbMigrate : Successfully applied 2 migrations to schema `flyway_test` (execution time 00:00.373s)
9 2022-08-30 10:15:25.799 INFO TID: N/A 98445 --- [ main][] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
10 2022-08-30 10:15:25.851 INFO TID: N/A 98445 --- [ main][] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.7.Final
11 2022-08-30 10:15:25.980 INFO TID: N/A 98445 --- [ main][] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
12 2022-08-30 10:15:26.173 INFO TID: N/A 98445 --- [ main][] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
13 2022-08-30 10:15:26.311 INFO TID: N/A 98445 --- [ main][] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
14 2022-08-30 10:15:26.319 INFO TID: N/A 98445 --- [ main][] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
执行后数据库 flyway_schema_history 表新增 SQL 变更记录
版本降级
1 mvn flyway:undo
2 [ERROR] Failed to execute goal org.flywaydb:flyway-maven-plugin:6.0.8:undo (default-cli) on project redis-test: org.flywaydb.core.internal.license.FlywayProUpgradeRequiredException: Flyway Pro Edition or Flyway Enterprise Edition upgrade required: undo is not supported by Flyway Community Edition.
* 很遗憾,flyway 社区版不支持 undo 功能。
在 Zadig 上实践 flyway
参考「Zadig + Flyway 工作流统一数据和代码变更,研发更丝滑」[5]
go-migrate
前置准备
安装 migrate
从官方下载 migrate 工具 [6]并安装 ,选择适合自己电脑操作系统和芯片架构的二进制文件。
准备数据库
使用 Datagrip 工具创建测试数据库用于 demo
1 create database redis_test default character set utf8mb4 collate utf8mb4_unicode_ci;
准备项目
准备 spring boot 测试项目 migration-test,编写 migrate sql
1 # 1_initialize_schema.up.sql
2 # 如果是业务表,可以考虑create table if not exists
3 create table alert
4 ...
5 charset = utf8mb4;
67 create index IX_alert_select_1
8 ...
1 # 1_initialize_schema.down.sql
2 # 如果是业务表,里面有业务数据,建议版本回退的时候不做drop操作
3 drop table if exists alert;
将 SQL 变更记录(各版本增量更新的 up、down 语句)保存在项目指定目录下,发布时,执行 migrate up 命令。示例如下:
文件命名规则:
1 {version}_{title}.up.{extension}
2 {version}_{title}.down.{extension}
参数说明:
{version} —— 64 位无符号整数,该值需要随着版本趋势增长并保持唯一,比如1,2,3,4...
{title} —— 本次 SQL 变更的简单英文标识
{extension} —— SQL 变更文件后缀,比如.sql
本地验证
migrate 组件目前对支持 多个微服务共用一个数据库,且都需要改变表结构 的场景还不完善,可以考虑在原生功能的基础上进行二开,下述内容为二开后的实践。
1. 执行 migrate up 命令,自动执行所有 up.sql,更新到最新版本
1 shell➜ migrate-test git:(master) ✗ migrate -appname "migrate-test" -source "file://migrations" -database "mysql://root:root@tcp(localhost:3306)/migrate_test" up
2 1/u initialize_schema (180.104ms)
3 2/u create_route (276.570667ms)
4 3/u create_notify (380.573625ms)
2. 执行 migrate down 1 命令,回退版本3
1 shell➜ migrate-test git:(master) ✗ migrate -appname "migrate-test" -source "file://migrations" -database "mysql://root:root@tcp(localhost:3306)/migrate_test" down 1
2 3/d create_notify (39.362042ms)
3. 执行 migrate down 命令,回退到初始状态
1 shell➜ migrate-test git:(master) ✗ migrate -appname "migrate-test" -source "file://migrations" -database "mysql://root:root@tcp(localhost:3306)/migrate_test" down
2 Are you sure you want to apply all down migrations? [y/N]
3 y
4 Applying all down migrations
5 2/d create_route (73.9035ms)
6 1/d initialize_schema (116.148333ms)
4. 执行 migrate goto 2 命令,更新到指定中间版本2
1 shell➜ migrate-test git:(master) ✗ migrate -appname "migrate-test" -source "file://migrations" -database "mysql://root:root@tcp(localhost:3306)/migrate_test" goto 2
2 1/u initialize_schema (178.743125ms)
3 2/u create_route (280.408375ms)
5. 执行 migrate down 1 命令,回退版本2
1 shell➜ migrate-test git:(master) ✗ migrate -appname "migrate-test" -source "file://migrations" -database "mysql://root:root@tcp(localhost:3306)/migrate_test" down 1
2 2/d create_route (52.728416ms)
6. 执行 migrate down 1 命令,回退版本1
1 shell➜ migrate-test git:(master) ✗ migrate -appname "migrate-test" -source "file://migrations" -database "mysql://root:root@tcp(localhost:3306)/migrate_test" down 1
2 1/d initialize_schema (56.16175ms)
在 Zadig 上实践 go-migrate
1. 将服务添加到 Zadig 中并创建构建,在构建脚本中添加 migrate 命令及相关参数,将代码中的 .sql 文件应用到数据库
2. 运行工作流,验证代码中的 SQL 和数据库存在差异时的效果(初次运行将变更应用到数据库,显示变更对应的文件及执行耗时)
再次运行工作流,验证代码中的 SQL 和数据库无差异时的效果(第二次运行,无 SQL 变更,显示 no change )
当数据库中的 SQL 版本低于代码中时, migrate up 命令会将数据库中的 SQL 更新到和代码一致;当数据库中的 SQL 与代码中一致时, migrate up 命令不会执行任何操作。
参考链接
[1] https://github.com/golang-migrate/migrate
[2] https://github.com/flyway/flyway
[3] https://flywaydb.org/download
[4] https://flywaydb.org/download/community
[5] https://mp.weixin.qq.com/s/KFyKkYTQp58BpNn9HGA7AQ
[6] https://github.com/golang-migrate/migrate/releases
Zadig,让工程师更专注创造!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
DevOps整合Jenkins+k8s+CICD
作者:大虾别跑 原文链接:https://blog.csdn.net/qq_35583325/article/details/126936804 转自:IT运维技术圈 一、DevOps介绍 软件开发最开始是由两个团队组成: 开发计划由开发团队从头开始设计和整体系统的构建。需要系统不停的迭代更新。 运维团队将开发团队的Code进行测试后部署上线。希望系统稳定安全运行。 这看似两个目标不同的团队需要协同完成一个软件的开发。 在开发团队指定好计划并完成coding后,需要提供到运维团队。 运维团队向开发团队反馈需要修复的BUG以及一些需要返工的任务。 这时开发团队需要经常等待运维团队的反馈。这无疑延长了事件并推迟了整个软件开发的周期。 会有一种方式,在开发团队等待的时候,让开发团队转移到下一个项目中。等待运维团队为之前的代码提供反馈。 可是这样就意味着一个完整的项目需要一个更长的周期才可以开发出最终代码。 基于现在的互联网现状,更推崇敏捷式开发,这样就导致项目的迭代速度更快,但是由于开发团队与运维团队的沟通问题,会导致新版本上线的时间成本很高。这又违背的敏捷式开发的最初的目的。 那...
- 下一篇
EasyGoAdmin 敏捷开发框架 Gin+AntdVue 版本 v1.5.0 发布
v1.5.0 更新内容: 1、新增图片上传时图片裁剪的功能; 2、修复用户编辑行政区划选择强制验证的问题; 3、修复近期用户反馈的 BUG; 项目介绍 一款 Go 语言基于 Gin、Xorm、Vue、AntDesign、MySQL 等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可快速搭建前后端分离后台管理系统,本着简化开发、提升开发效率的初衷,框架自研了一套个性化的组件,实现了可插拔的组件式开发方式,同时为了敏捷快速开发,框架特地集成了代码生成器,完全自主研发了自定义 GO 后端服务模板和前端 Vue 自定义模板,可以根据已建好的表结构,可以快速的一键生成整个模块的所有代码和增删改查等等功能业务,真正实现了低代码开发方式,极大的节省了人力成本的同时提高了开发效率,缩短了研发周期,是一款真正意义上实现组件化、可插拔式的敏捷开发框架。 项目特点 模块化、松耦合 模块丰富、开箱即用 简洁易用、快速接入 文档详尽、易于维护 自顶向下、体系化设计 统一框架、统一组件、降低选择成本 开发规范、设计模式、代码分层模型 强大便捷的开发工具链 完善的本地中文化支持 设计为团队及...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Hadoop3单机部署,实现最简伪集群
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker安装Oracle12C,快速搭建Oracle学习环境