【问题标题】:Why do I get a SocketTimeoutException when trying to connect to a RDS PostgreSQL DB in Java?尝试连接到 Java 中的 RDS PostgreSQL 数据库时,为什么会收到 SocketTimeoutException?
【发布时间】:2021-11-28 13:51:27
【问题描述】:

我有一个 Spring 应用程序,我正试图将其托管在 AWS 上,但我已经在配置方面苦苦挣扎了几天。

我有一个 EC2 实例,并且能够使用 SSH 连接到它。我还在 AWS 中设置了 Postgres RDS 数据库,但我无法使用 IDE 中的代码连接到它,因此我还没有将应用程序上传到 EC2 实例。

我认为问题出在我的安全组上,因为我的 application.properties 出现的方式与 AWS 文档和其他指南所建议的一样。

我一直在努力了解安全组的来龙去脉,但这一直是一场斗争。我认为在实际生产环境中准确使用我的 SG 非常重要,但我只是尝试将此应用程序用作演示。

任何允许连接到 RDS 数据库的松散配置现在都对我有用。

application.properties

spring.datasource.url=jdbc:postgresql://myEndpoint:myPort/myAppName
spring.datasource.username=myDbUsername
spring.datasource.password=myDbPassword
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgresPlusDialect
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
spring.session.jdbc.initialize-schema=always
spring.session.store-type=jdbc
spring.session.jdbc.table-name=spring_session
server.servlet.session.timeout=30m

我尝试了多个 SG 配置,这里有 2 个示例:


RDS 配置 1

Public accessibility: Yes
VPC Security Groups: launch-wizard-1 (sg-id-1) / Active

sg-id-1

Inbound rules:
rule 1 -- IP version: IPv4, Type: SSH, Protocol: TCP, Port range: MySSHPort, Source: 0.0.0.0/0
rule 2 -- IP version: IPv4, Type: Custom TCP, Protocol: TCP, Port range: MyLocalPort, Source: 0.0.0.0/0

Outbound rules:
rule 1 -- IP version: IPv4, Type: All traffic, Protocol: All, Port range: All, Destination: 0.0.0.0/0

RDS 配置 2

Public accessibility: Yes
VPC Security Groups: default (sg-id-2) / Active

sg-id-2

Inbound rules:
rule 1 -- Type: PostgreSQL, Protocol: TCP, Port range: 5432, Source: sg-id
rule 2 -- Type: All traffic, Protocol: All, Port range: All, Source: sg-id

Outbound rules:
rule 1 -- IP version: IPv4, Type: All traffic, Protocol: All, Port range: All, Destination: 0.0.0.0/0

当我尝试连接 RDS 上设置的任一安全组时,连接超时并显示 SocketTimeoutException

这是什么原因造成的?


编辑:它终于连接了。最终允许访问的安全组配置是:

Inbound rules:
rule 1 -- Type: PostgreSQL, Protocol: TCP, Port range: 5432, Source: 0.0.0.0/0

Outbound rules:
N/A

我还向互联网网关添加了一个子网路由表,我认为这是必要的,尽管它最初不允许访问,因为 SG 入站规则上的源仍然不正确。

【问题讨论】:

  • 感谢您提出明确的问题 - 连接字符串绝对正确吗?尝试使用常规 SQL 客户端来查看它是您的 Java 代码还是您的 RDS 配置 - 例如SQL Electron
  • 感谢您的回复!不幸的是,SQL Electron 没有任何运气。我很确定连接字符串是正确的。除了不一定包括一两个教程中的端口之外,我真的找不到与我使用的模式的任何变化。我尝试了两种方法都没有运气,我使用的端点是直接从 AWS 上的管理控制台复制的。
  • 不用担心 Stephen - 可以设置为您的第二个安全组配置,但是删除第一个 5432 规则。确保 SG 在任何地方都应用 - 现在可以使用 SQL 客户端连接到它吗?
  • 我的 Sqlectron 和我的 IDE 仍然超时。更清楚地说,默认的 sg-id-2 应用于 RDS 和 EC2 实例,并且对于入站和出站只有一个“所有流量”规则。这让我觉得我在端点上做错了什么。在 Sqlectron 中,我使用 RDS 管理控制台中 Endpoint 下的完整条目作为服务器地址。
  • 啊抱歉,我很困惑,因为当我从 RDS 控制台单击安全组时,它会将我带到 EC2 管理控制台。这是否意味着我的 RDS 设置没有特定的安全组?是的,它可以公开访问。

标签: java postgresql amazon-web-services amazon-ec2 amazon-rds


【解决方案1】:

SocketTimeoutException 表示您的应用程序无法从端点(在本例中为数据库)返回响应。

您的 RDS 配置一定有问题,您可以检查以下几点。


1.安全组 (SG) 入站和出站规则

就您的 SG 配置而言,安全组是有状态的。

这意味着,如果您创建允许流量进入的入站规则,则无论任何出站规则如何,都会自动允许该流量返回。

因此,公共 PostgreSQL RDS 数据库的最佳配置是:

Inbound rules:
rule 1 -- Type: PostgreSQL, Protocol: TCP, Port range: 5432, Source: 0.0.0.0/0

Outbound rules:
N/A

如果您的入站规则不允许 PostgreSQL 流量通过,您的请求将永远不会到达数据库 - 安全组将应用于实例级别。


2。 “公共可访问性”RDS 属性

如果安全组设置正确,请仔细检查RDS实例的“网络和安全”中的“公共可访问性”属性是否设置为“是”。

这将为 RDS 实例分配一个公共 IP 地址以供外部访问,公共 IP 地址是公共数据库的要求。


3.子网类型

如果你的 SGS 没问题并且你的数据库有公共 IP 但你没有Internet Gateway,就好像你买了宽带连接到互联网但你的网线被拔掉了(缺少一个互联网网关)。

要让 RDS 实例可公开访问,您还需要在数据库的子网中创建 Internet Gateway。创建后,您需要将 Internet 绑定流量定向到 Internet 网关。

为此,请设置子网的路由表以将所有数据路由到0.0.0.0/0(作为目标的互联网绑定 IPv4 流量)到互联网网关 ID(目标)。

这将使您的子网公开,因为该子网现在与一个路由表相关联,该路由表具有到互联网网关的路由。

公共子网是公共数据库的另一个要求,因为这将确保您的 VPC 和互联网之间可以进行通信。

没有互联网网关的私有子网将不允许外部访问。


4. DNS 主机名和 DNS 解析 VPC 属性

如果您仍然无法公开访问您的数据库,请确保 RDS 实例所在的 VPC 的 DNS hostnames & DNS resolution VPC attributes are enabled


5.网络 ACL

检查您是否创建任何处于默认状态的 network ACLs 或具有阻止规则的与子网关联的 NACL。

默认创建的 NACL 会像防火墙一样阻止所有入站和出站流量,无论安全组设置如何,除非您添加明确允许它们的规则。

您的 VPC 将附带一个默认 NACL,它允许所有入站和出站 IPv4 流量 - 使用那个。


6.身份验证

确保您的用户名和密码/IAM 身份验证令牌/Kerberos 凭证 100% 正确。


以上是一个非常全面的列表,因此希望其中一个建议可以让您从外部连接到数据库并排除您的 Java 代码不正确。

然后您可以将 RDS 实例设为私有,只接受来自您的 EC2 实例安全组的流量,并从您的子网中删除互联网网关以使其私有,applying the security at all layers AWS 井中的安全支柱原则- 架构框架。

【讨论】:

  • 感谢您的完整列表。这很棒,我一路上学到了一些东西。不幸的是,在应用您的 SG 的确切示例后,我仍然超时,确保它是可公开访问的,检查 DNS 主机名和解析是否启用,确保所有 ACL 规则都是默认的,并确保设置了路由表对于我的目标为 0.0.0.0/0 的 Internet 网关。我很茫然。这让我觉得我在 RDS 的设置中做了一些奇怪的事情。唯一让我感到困惑的地方是网关/路由,我将在下面详细说明。
  • 我创建了一个新的 Internet 网关,但我无法附加它,因为已经设置并附加了一个。我决定为那个网关设置一个路由表。我在 0.0.0.0/0 处创建了一个新路由,其目标是连接到我的 VPC 的网关。当我附加它时,有 6 个可能的子网可以关联,我检查了它们,至少现在是这样。这条路线的状态是活跃的。据我了解,这就是我所要做的!
  • 啊我知道 - 我在上面发布的 SG 的来源是 sg-id,我忘了从你的原始帖子中更改它 - 将来源设置为 0.0.0.0/0 以允许任何 IP 连接 - 确实那工作?另外 - 您没有使用 IPv6 地址进行连接,是吗?最后一点 - 如果使用身份验证,用户名和密码是否 100% 正确?并确保您拥有 VPC 附带的默认 NACL 规则,否则删除规则意味着默认情况下它们将阻止所有内容
猜你喜欢
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 2015-12-01
  • 2021-09-10
  • 2014-02-26
相关资源
最近更新 更多