【问题标题】:Dockerized Spring Boot + Postgres connection refusedDockerized Spring Boot + Postgres 连接被拒绝
【发布时间】:2020-12-31 22:17:05
【问题描述】:

尝试启动一个使用 docker-compose 连接到两个 PostgreSQL 数据库的 Spring Boot 应用程序,但当 Spring 尝试连接到这两个数据库中的任何一个时,连接被拒绝。

我的配置如下:

docker-compose.yml

version: '3.2'
services:
  mydb-1:
    container_name: mydb-1
    image: mydb-1
    ports:
      - '5432:5432'
    environment:
         - POSTGRES_PASSWORD=postgres
         - POSTGRES_USER=postgres
         - POSTGRES_DB=testdb1
  mydb-2:
    container_name: mydb-2
    image: mydb-2
    ports:
      - '5433:5432'
    environment:
          - POSTGRES_PASSWORD=postgres
          - POSTGRES_USER=postgres
          - POSTGRES_DB=testdb2
  my-server:
    image: my-server-spring
    restart: on-failure
    depends_on:
      - mydb-1
      - mydb-2
    environment:
      - SPRING_DB1-DATASOURCE_JDBC-URL=jdbc:postgresql://mydb-1:5432/testdb1
      - SPRING_DB2-DATASOURCE_JDBC-URL=jdbc:postgresql://mydb-2:5433/testdb2
    expose:
      - '8080'
    ports:
      - '8080:8080'

春天application.properties

spring.db1-datasource.jdbc-url= jdbc:postgresql://localhost:5432/testdb1
spring.db1-datasource.username= postgres
spring.db1-datasource.password= postgres
spring.db1-datasource.driverClassName= org.postgresql.Driver

spring.db2-datasource.jdbc-url= jdbc:postgresql://localhost:5433/testdb2
spring.db2-datasource.username= postgres
spring.db2-datasource.password= postgres
spring.db2-datasource.driverClassName= org.postgresql.Driver

Stacktrace(部分)

org.postgresql.util.PSQLException: Connection to testdb2:5433 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

advidi-server_1         |       at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:285) ~[postgresql-42.2.14.jar!/:42.2.14]
advidi-server_1         |       at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.14.jar!/:42.2.14]
advidi-server_1         |       at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:217) ~[postgresql-42.2.14.jar!/:42.2.14]
advidi-server_1         |       at org.postgresql.Driver.makeConnection(Driver.java:458) ~[postgresql-42.2.14.jar!/:42.2.14]
advidi-server_1         |       at org.postgresql.Driver.connect(Driver.java:260) ~[postgresql-42.2.14.jar!/:42.2.14]
advidi-server_1         |       at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:358) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:477) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:560) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-3.4.5.jar!/:na]
advidi-server_1         |       at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
advidi-server_1         |       at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]

最初我认为问题在于 Spring 应用程序在引导完成之前试图连接到 dbs,但情况似乎并非如此,因为使用 restart: on-failure 它应该在某个时候设法连接.

默认的localhost 值也应该不是问题,因为它们已被我的 docker-compose 文件中的环境变量替换。

有什么想法吗?

【问题讨论】:

  • 你很高兴忘记在你的帖子中包含实际的堆栈跟踪/错误。
  • 我很高兴地添加了它:)
  • 您的第二个 dockerized 数据库是否正常启动?

标签: postgresql spring-boot docker docker-compose database-connection


【解决方案1】:

您在环境中传递SPRING_DB1-DATASOURCE_JDBC-URL,而不是在 application.properties 中使用它。所以变量没有被覆盖。

您需要在 application.properties 中使用类似
spring.db1-datasource.jdbc-url=$SPRING_DB1-DATASOURCE_JDBC-URL

在环境中设置应用程序中变量的确切名称。属性
- spring.db1-datasource.jdbc-url=jdbc:postgresql://mydb-1:5432/testdb1

我建议第二个选项,它仍然允许您使用 application.properties 作为本地运行的默认值。

【讨论】:

    【解决方案2】:

    您没有显示 mydb-1mydb-2 图像配置,所以我实际上是在这里猜测。

    1. 无需将端口映射到主机。删除 ports: 条目。
    2. spring 容器应使用端口 5432 以连接到两个 DB 容器。每个数据库容器都有自己的 IP,所以没有问题。不要连接到localhost,因为那是容器本身。
    3. 无需在连接字符串中指定:5432,因为这是默认设置。
    4. 似乎您在服务器配置中的application.propertiesenvironment: 条目中都有连接设置。应用程序使用的是哪个?无论如何,您的连接字符串应该以 mydb-1/testdb1mydb-2/testdb2 结尾 - 没有比这更复杂的了。

    【讨论】:

    • 是的,我没有添加相应的 Dockerfile,因为它们非常基础。你的建议似乎有效,但我真的不明白为什么。请详细说明为什么?另外,删除“端口”是否意味着我无法访问容器外的数据库?
    • 我认为您试图从应用程序容器中访问 localhost。在容器内,localhost 表示“这个容器”而不是“我的 docker 主机”。当您指定邻居容器名称(mydb-1、mydb-2)时,您就可以访问它们。如果您需要从外部访问,则可以返回 ports: 条目,但要考虑到容器本身不使用它们。
    猜你喜欢
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 2018-09-22
    • 2019-06-06
    • 2021-04-24
    • 2023-01-08
    • 2018-07-03
    • 2018-08-29
    相关资源
    最近更新 更多