Flyway 在 Spring Boot 上不工作时如何调试?

Posted

技术标签:

【中文标题】Flyway 在 Spring Boot 上不工作时如何调试?【英文标题】:How to debug when Flyway doesn't work on Spring Boot? 【发布时间】:2017-09-15 17:29:48 【问题描述】:

我正在使用 Maven 和 Spring Boot。我使用mvn spring-boot:run 运行应用程序。

https://flywaydb.org/documentation/plugins/springboot 表示应在 Spring Boot 启动时调用 Flyway。

所以我的 pom.xml 包含对 Flyway 的依赖。

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>4.1.2</version>
</dependency>

我第一次运行上面的 Maven 命令时,它下载了 Flyway 的东西,所以我认为依赖项正在工作。

我有以下文件:

./src/main/resources/db/migration/V123__foo.sql
./src/main/resources/application.properties

上面的文章暗示它应该“正常工作”,但我不明白它会在哪里找到数据库的 JDBC URL。所以我在application.properties 文件中添加了以下内容:

flyway.url=jdbc:postgresql://localhost:5432/services?user=postgres&password=postgres
flyway.enabled=true

当 Spring Boot 启动(并加载并启用我的 Web 应用程序)时,Flyway 没有日志。我认为 Flyway 被忽略了。

我能做什么?或者,更一般地说,我将如何自己调试这个问题?

【问题讨论】:

flyway 默认使用spring.datasource属性指定的普通数据源,一般不需要额外的。如果你真的想为 flyway 使用单独的 URL 和用户,你需要 flyway.urlflyway.usernameflyway.password,而不是嵌入在 URL 中。旁边确保你有一个数据库驱动程序,否则没有检测到 JDBC 并且不会运行任何东西(没有 JDBC 它不会工作)。 感谢您的建议。虽然没有错误,应用程序“运行”(只是没有调用 Flyway),我怀疑(希望?)如果数据源错误(例如没有 JDBC 驱动程序),那么它会打印一个错误,或者我错了那个假设? 如果您已经在使用数据源,那么默认情况下将使用该数据源。你还期待看到什么?日志记录取决于您的日志级别,如果它很高(WARN 或其他东西),您将看不到任何东西。您可能希望检查数据库的内容,而不是依赖日志记录。 我目前没有使用数据源(这是一个新项目)。根据docs.spring.io/spring-boot/docs/current/reference/html/…“或者你可以通过在外部属性中设置flyway.[url,user,password]来使用Flyway的原生DataSource。”所以设置 flyway.xx 属性并运行 Spring Boot 应用程序不仅不会记录,也不会影响数据库。 (如果我使用 Maven 的 Flyway 插件,在构建期间进行迁移,那么数据库会被迁移,所以我认为迁移文件是正确的位置。但我想在 Spring Boot 启动时) 正如我在第一条评论中所说,如果您已经在使用数据源,那么 if 只会起作用。如果你不是,它什么也做不了。 flyway 配置取决于数据源的可用性。如果这不可用,flyway 将被禁用。 【参考方案1】:

没有人发布答案,所以我将发布我发现的内容。

M. Deinum 在他们的问题中确实是正确的,问题是缺乏数据源。

我最初的问题是调试此类问题的方法应该是什么。显然,一种选择是发布到 *** :) 但我想知道如何自己做。

Spring Boot 有许多类,它们会查看您的代码和类路径,并采取适当的行动。例如,有些类提供了“如果 Flyway 在路径上,并且有数据源,则执行 Flyway”等规则的实现。在我的情况下,该规则没有被触发,因为我没有数据源。

并不是你写的代码调用 Spring Boot,而是反过来,Spring Boot(在你的代码之外)会检查你的代码并根据规则决定做什么。这种架构被称为action at a distance。远距离动作的主要问题是很难调试。

找到解决方案的唯一真正方法,也是我确认 M. Deinum 诊断的方法,是阅读 Spring Boot 源代码并理解用于创建 Spring Boot 代码的注释。

从源码到Spring Boot's Flyway integration我们看到

@ConditionalOnClass(Flyway.class)
@ConditionalOnBean(DataSource.class)

这意味着“如果 Flyway 在类路径上,并且如果有可用的 DataSource bean,则此代码将被执行;否则它不会被静默执行”。

所以“如何调试这个问题”这个问题的答案是除了阅读Spring Boot的源代码并了解它是如何工作的之外,没有其他机制。

如果您想避免此类问题,您必须避免使用通过“远距离操作”工作的框架,其中包括 Spring Boot。

【讨论】:

不幸的是,“Spring Boot 的 Flyway 集成”链接已损坏。我想我正面临着 the same issue 的飞行路线没有在春天运行。 感谢@StefanFalk 的提醒。我现在已经更正了。

以上是关于Flyway 在 Spring Boot 上不工作时如何调试?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Spring Boot 项目中使用 Flyway 时撤消迁移不起作用?

Flyway 和 Spring Boot 集成

无法在 Spring Boot 中将 Flyway 迁移与 postgresQL 连接起来

Spring-Boot 不适用于 Flyway

使用 Spring Boot 进行 Flyway 修复

无法将docker Spring-Boot应用程序与docker-compose中的mysql容器和flyway连接起来