Spring Boot 如何知道 Heroku 的 DATABASE_URL 配置变量?

Posted

技术标签:

【中文标题】Spring Boot 如何知道 Heroku 的 DATABASE_URL 配置变量?【英文标题】:How is Spring Boot aware of Heroku's DATABASE_URL config var? 【发布时间】:2019-05-02 11:37:40 【问题描述】:

短篇小说:

Spring Boot 究竟是如何解析 DATABASE_URL 配置变量的?在我的本地 PC 上设置具有相同名称的环境属性无效。涉及 Spring Boot 库中的哪些类?在DATABASE_URL 上进行全文搜索不会返回任何内容。

长篇大论:

我最近向 Heroku 部署了一个简单的 Spring Boot + JPA 应用程序。我的 heroku 已经配置了 Postgres 插件。

在我的第一次部署期间,我只想确认应用程序可以正确构建和启动。但令我惊讶的是,该应用程序立即连接到在 Heroku 的 DATABASE_URL config var 中配置的 Postgres 数据库:

2018-11-30T09:28:51.054688+00:00 app[web.1]: 2018-11-30 09:28:51.054  INFO 4 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL95Dialect

这让我想到了上面已经发布的问题。

我正在使用 Spring boot 2.1.0.,simple app 由 Spring Initializr 创建,Web + JPA + H2 + PostgreSQLH2 包含在内,因为:

我想使用嵌入式 H2 运行单元测试 大多数时候,我想使用嵌入式 H2 在本地运行我的应用程序,但有时,我想切换到 Heroku 的 Postgres,以便验证一些特定于数据库的内容(例如迁移)

【问题讨论】:

【参考方案1】:

我将回答我自己的问题,用有关 Heroku 设置的环境属性的更多详细信息来修改已接受的答案。

假设您的 Heroku 应用程序包含环境变量:

DATABASE_URL = postgres://username:password@host:port/database

Heroku 将自动提供以下环境变量(您可以在例如您最喜欢的基于 JDBC 的 SQL 客户端中使用):

JDBC_DATABASE_URL = jdbc:postgresql://host:port/database?user=username&password=password&sslmode=require JDBC_DATABASE_USERNAME = username JDBC_DATABASE_PASSWORD = password

还有那些被 Spring Boot 自动拾取的(你可以用它来修改你的本地 Spring Boot 配置文件:

SPRING_DATASOURCE_USERNAME = 与 JDBC_DATABASE_USERNAME 相同 SPRING_DATASOURCE_PASSWORD = 与 JDBC_DATABASE_PASSWORD 相同 SPRING_DATASOURCE_URL = 与 JDBC_DATABASE_URL 相同

我通过使用简单的 REST 端点观察到这一点:

@RequestMapping("/env")
public @ResponseBody Map<String, String> env() 
    return System.getenv();

小心,不要犯和我一样的错误:DATABASE_URLpostgres 开头,而 Postgres 的 JDBC 前缀是 postgresql。使用带有前缀jdbc:postgres://SPRING_DATASOURCE_URL 会导致以下错误:

驱动 org.h2.Driver 声称不接受 jdbcUrl, jdbc:postgres://....

【讨论】:

【参考方案2】:

Spring 不知道DATABASE_URL(据我所知)。但它会检测并自动使用 Heroku Java buildpack 在运行时设置的SPRING_DATASOURCE_URL

您可以在 Connecting to Relational Databases on Heroku with Java 上的 Heroku 文档中阅读有关此 env var 的更多信息

【讨论】:

【参考方案3】:

为了能够在 h2 和 heroku 之间轻松切换,可以有 2 个配置文件

名为 application-h2.properties 的 h2 属性文件:

spring.profiles.active=h2
spring.datasource.url= # H2 URL of the database.
spring.datasource.driver-class-name=# H2 JDBC driver. Auto-detected based on the URL by default.
spring.datasource.password= # Login password of the database.
spring.datasource.username= # Login username of the database.

通过在运行 spring boot 应用时将 h2 配置文件设置为 on 来激活:

java -jar -Dspring.profiles.active=h2 myApplication.jar

名为 application-heroku.properties 的 heroku 属性文件:

spring.profiles.active=heroku
spring.datasource.url= # herokuURL of the database.
spring.datasource.driver-class-name=# herokuJDBC driver. Auto-detected based on the URL by default.
spring.datasource.password= # Login password of the database.
spring.datasource.username= # Login username of the database.

通过在运行 spring boot 应用程序时将 heroku 配置文件设置为开启来激活:

java -jar -Dspring.profiles.active=heroku myApplication.jar

【讨论】:

以上是关于Spring Boot 如何知道 Heroku 的 DATABASE_URL 配置变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter+Spring Boot+PostgreSQL+Heroku 结构中发送和存储图像?

我如何将本地 PostgreSQL 数据库复制到 Heroku for Spring Boot 应用程序

Heroku H14(没有运行 Web 进程)+ Spring-boot

Heroku Spring Boot 不构建 Jar

从 Spring Boot 连接到 Heroku Postgres

使用 nginx 作为代理的 Spring Boot 应用程序部署在 Heroku 上