在微服务场景下应用Liquibase

介绍

Liquibase是一款成熟的数据库版本控制工具,支持多种数据库,多种描述文件格式,以及多种数据库操作手段(原生change type、Java自定义change type)。

在单体服务中,应用Liquibase是一件很轻松的事情,只需要按照要求配置好相关属性即可。但是在微服务场景下,就需要仔细考量一番。

单体服务

在单体服务中,通常只使用一种数据库的一个实例,在该情况下,如果是Spring应用,则只需要在application.yml中设置必要属性,然后服务启动的时候,会自动执行Liquibase的update操作。

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db-test
    username: root
    password: 123456
  liquibase:
    change-log: classpath:db/changelog/changelog.xml

因为spring.liquibase.change-log指向了classpath:db/changelog/changelog.xml,所以在src/main/resources目录下,需要创建db/changelog/changelog.xml文件。

以下是一个官方的示例:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
    <changeSet id="1" author="saas">
        <createTable tableName="test_table">
            <column name="test_id" type="int">
                <constraints primaryKey="true"/>
            </column>
            <column name="test_column" type="varchar(255)"/>
        </createTable>
    </changeSet>
</databaseChangeLog>

微服务

在微服务场景下,其实主要的问题,是如何放置changelog文件,可以有两种方案:

集中放置

方式:将所有微服务使用到的所有changelog文件集中放在一个地方(比如:gitlab上的一个独立项目)。目录结构大致如下:

lua 复制代码
liquibase
    +-- changelog-root.xml
    +-- <module-name>
            +-- changelog-1.0.xml
            +-- changelog-1.1.xml

即:

  • changelog-root.xml是入口文件,它会includes所有子目录下其他changelog文件
  • 每个模块做成一个目录
  • 在每个模块目录下,是按照版本划分的changelog文件

适用场景

适合所有微服务使用同一个数据库实例的场景。

部署说明

在部署到k8s时,为了让每个pod都能访问到这些集中放置的changelog文件,可以使用PV或者DaemonSet的方式,让这些changelog文件对pod可见,而且使用统一的目录名。

局限性

将来一旦有微服务必须使用单独的数据库实例,那么就必须再设计一套独立的changelog目录,从而打破了集中放置的初衷。

分散放置

方式:每个微服务都可能有一套changelog文件,放置在每个微服务的src/main/resources/liquibase目录下。目录结构大致如下:

lua 复制代码
src/main/resources/liquibase
    +-- changelog-root.xml
    +-- <微服务名>
            +-- changelog-1.0.xml
            +-- changelog-1.1.xml

即:

  • changelog-root.xml是入口文件,它会includes所有子目录下其他的changelog文件
  • <微服务名>建议使用${spring.application.name},以区分不同的微服务(为什么需要一个微服务名的目录?为的是将来万一要按照模块集中放置changelog文件,可以很方便的拷贝并合并这些文件)
  • 每个<微服务名>目录下,是按照版本划分的changelog文件

适用场景

适合每个微服务使用独立数据库实例的场景。当然,它也兼容所有微服务使用同一个数据库实例的场景,甚至是混合场景。

而且最好一个人负责一整个模块,而不要只负责某个模块的部分微服务。

部署说明

不需要特殊的部署

局限性

这种方式提供了很高的灵活性和可扩展性,但同时也提高了开发的复杂性和维护难度,体现在:

  • 每个模块的不同微服务之间,必须确保不会操作相同的表
  • 在一个人维护多个模块的情况下,需要在不同模块之间切换,容易产生"手误"

结论

在微服务场景下,如果使用了集中放置changelog文件的方案,则需要特定的部署(PV或者DaemonSet)来配合。如果使用了分散放置changelog文件的方案,则开发方式与单体服务没有区别,问题就在于通过管理手段实现微服务之间表冲突的问题。

相关推荐
亦世凡华、5 分钟前
MySQL--》如何在MySQL中打造高效优化索引
数据库·经验分享·mysql·索引·性能分析
YashanDB7 分钟前
【YashanDB知识库】Mybatis-Plus调用YashanDB怎么设置分页
数据库·yashandb·崖山数据库
ProtonBase18 分钟前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
乐之者v24 分钟前
leetCode43.字符串相乘
java·数据结构·算法
suweijie7684 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿4 小时前
List深拷贝后,数据还是被串改
java
云和数据.ChenGuang6 小时前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
woshilys6 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi6 小时前
SQL注入的那些面试题总结
数据库·sql
建投数据7 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云