在微服务场景下应用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文件的方案,则开发方式与单体服务没有区别,问题就在于通过管理手段实现微服务之间表冲突的问题。

相关推荐
葡萄成熟时 !8 小时前
JAVA 常用API学习笔记
java·笔记·学习
Lyyaoo.9 小时前
Spring Boot Validation 声明式参数校验
spring boot·后端·mysql
Rain的Java大神之路9 小时前
介绍一下分布式事务
java·分布式·后端·spring·spring cloud·架构·springcloud
oradh10 小时前
Oracle闪回技术操作总结
数据库·oracle·oracle闪回技术操作总结·oracle闪回·flashback技术
吴声子夜歌10 小时前
Java面试题——基础(一)
java·开发语言
南城以南溫暖如初14710 小时前
外卖CPS实战指南:从技术选型到运营落地全流程解析
java·spring boot·mysql·架构·vue
ltl10 小时前
RocksDB 并发 Compaction 与 Rate Limiter
数据库
傻啦嘿哟11 小时前
英雄联盟皮肤爬虫:爬取全皮肤价格与特效,做比价工具
java·c++·爬虫
码匠许师傅12 小时前
【C++ 面试真题】24. 聊聊 C++ 的时间日期处理
java·c++·面试
闻道且行之12 小时前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv