View a markdown version of this page

亚马逊 DocumentDB 的连接问题 - Amazon DocumentDB

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

亚马逊 DocumentDB 的连接问题

识别-发现问题

常见原因

连接问题通常源于三个主要方面:

当应用程序通过客户端连接池限制或服务器端实例限制达到其与 Amazon DocumentDB 的最大允许连接时,就会出现连接池耗尽。这种情况会导致应用程序性能降低、超时以及可能出现的故障,因为新的连接请求要么排队,要么被拒绝。

当 Amazon DocumentDB 遇到过多的并发身份验证请求时,尤其是在短时间内处理超过 1,000 个新连接时,就会出现身份验证过载。在身份验证维护期间,Amazon DocumentDB 在会话映射上保持独占锁,导致后续的身份验证尝试排队直到维护完成。

Amazon DocumentDB 中的配置问题通常源于网络、安全和客户端设置中的错误配置。这包括安全组设置不正确、VPC 配置不当或 SSL/TLS 证书问题等项目。了解正确的配置对于维护安全可靠的数据库访问至关重要。

诊断-找出根本原因

连接池

创建 MongoClient 实例时,连接池会初始化。每个池基于两个关键参数维护连接:

min PoolSize -保持的最小连接数

max PoolSize -允许的最大连接数

当请求需要连接时:

  1. 池检查是否有可用的空闲连接

  2. 如果不存在且池大小 < 最大值PoolSize,则会创建新连接

  3. 如果达到最大值PoolSize,则请求进入等待队列

  4. 如果队列已满或已达到超时,则会抛出 MongoWaitQueueFullException

等待队列的行为通过以下参数处理:

等待 QueueTimeout MS-连接的最大等待时间

等待 QueueSize -最大排队请求数

以下是连接到 Amazon DocumentDB 时出现问题的方法示例,其中每次都会创建一个新池:

for(Request request : requests) { MongoClient client = MongoClients.create(settings); // Process request client.close(); }

需要监控的关键 CloudWatch 指标是:

  • DatabaseConnections-以 1 分钟为频率开启的实例上打开的连接数(活跃和空闲)。

  • DatabaseConnectionsMax-1 分钟内一个实例上打开的最大数据库连接数(活动和空闲)。

  • DatabaseConnectionsLimit-在任何给定时间,一个实例上允许的最大并发数据库连接(活动和空闲)数。

  • LowMemNumOperationsThrottled-1 分钟内由于可用内存不足而受到限制的请求数量。

有关每个实例类的配额,请参阅实例限额

应用程序级别连接池问题的常见警告信号包括:

  • 增加连接获取时间

  • 等待队列大小不断增加

  • 超时异常数量不断增加

身份验证过载

连接亚马逊 DocumentDB 遵循类似于以下的流程:

连接请求 → SSL 握手 → 身份验证 → 会话创建 → 连接就绪

处理超过 1,000 个新连接时,完成 SSL 握手后,其他连接请求将进入身份验证队列。在这些过载事件期间,应用程序的平均连接时间将增加。

需要监控的关键 CloudWatch 指标是:

  • DatabaseConnections-以 1 分钟为频率开启的实例上打开的连接数(活跃和空闲)。

  • DatabaseConnectionsMax-1 分钟内一个实例上打开的最大数据库连接数(活动和空闲)。

  • DatabaseConnectionsLimit-在任何给定时间,一个实例上允许的最大并发数据库连接(活动和空闲)数。

配置问题

最常见的配置问题是在尝试从无法访问私有网络环境的环境连接到私有 Amazon DocumentDB 集群终端节点时引起的。Amazon DocumentDB 仅面向虚拟私有云(VPC),并且当前不支持公共端点。您无法从笔记本电脑或 VPC 外部的本地开发环境直接连接到 Amazon DocumentDB 集群。

这将体现在错误中,如下所示:

Error: couldn't connect to server... Failed to connect to... exception: connect failed connection attempt failed

不正确的安全组配置也可能导致连接失败。默认情况下,Amazon DocumentDB 集群监听 TCP 端口 27017 上的连接。如果尝试连接到与集群部署的端口不同的端口,或者该应用程序未包含在集群的入口安全组配置中,则您的应用程序将失败。

不正确的证书管理也可能导致连接问题。默认情况下,为新创建的 Amazon DocumentDB 集群启用传输中加密。启用传输中加密后,需要使用 TLS 的安全连接才能使用 global-bundle.pem 证书连接到集群。如果您尝试使用不正确的证书,则会收到错误,例如:

unable to get local issuer certificate

如果尝试在未指定 TLS 参数的情况下连接到启用了 TLS 的集群,则会收到以下错误:

Server selection timed out after 30000 ms

解决-修复问题

连接池:通过实施或调整池大小以满足工作负载要求来审查连接池。最佳池配置取决于您的工作负载和要求。你应该保持最短的PoolSize 时间,使核心连接准备就绪并可用,并且最大值应足够WaitTime 短,以便在池已用尽时快速失效。

以下是如何在不每次都创建一个新池的情况下重复使用单个池的示例:

MongoClient client = MongoClients.create(settings); for(Request request : requests) { // Process request }

身份验证过载:通过逐步增强连接并将新连接限制为每次 1,000 个来管理身份验证。使用连接池可以有效地重用经过身份验证的连接。为避免连接过载 Amazon DocumentDB 集群,请实施连接增强策略。

public class ConnectionManager { private static final int BATCH_SIZE = 100; private static final int DELAY_MS = 1000; public void establishConnections(int totalRequired) { int established = 0; while (established < totalRequired) { int batch = Math.min(BATCH_SIZE, totalRequired - established); createConnections(batch); Thread.sleep(DELAY_MS); established += batch; } } }

您还可以配置连接池设置以限制允许的连接总数。

MongoClientSettings settings = MongoClientSettings.builder() .applyToConnectionPoolSettings(builder -> { builder.maxSize(500) // Limit total connections .minSize(10) // Maintain base connections .maxConnectionLifeTime(3600000) // Rotate connections hourly }) .applyToServerSettings(builder -> { builder.heartbeatFrequency(10000) // Regular server checks }) .build();

配置问题:确保您的应用程序可以访问您的 Amazon DocumentDB 资源所在的私有 VPC 和子网。如果使用 VPC 对等连接,请查看开发人员指南 VPC 对等连接进行故障排除以了解更多信息。您还可以查看知识中心文章如何解决从互联网到我的 VPC 内的 Amazon EC2 实例的连接问题?

对于安全组配置,您必须在 Amazon DocumentDB 安全组中加入入口规则,以允许来自您的应用程序的连接。

{ "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 27017, "ToPort": 27017, "SourceSecurityGroupId": "<application-security-group>", "Description": "DocumentDB access from application tier" } ], "SecurityGroupEgress": [ { "IpProtocol": "-1", "FromPort": -1, "ToPort": -1, "CidrIp": "0.0.0.0/0" } ] }

如果集群配置了 TLS 加密,请下载名为 global-bundle.pem 的 Amazon Amazon DocumentDB 的 TLS 证书,并在连接到集群时使用该证书。

wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem

Long-term 解决方案

可能需要通过升级到更大的实例类或添加只读副本来分配连接负载来扩展实例。适当的负载平衡实现可确保整个集群的最佳资源利用率。

应用程序变更应侧重于实施强大的连接处理、全面监控和遵守连接池最佳实践。这包括适当的错误处理和连接生命周期管理。

架构改进可能包括采用 Amazon DocumentDB Serverless 来处理可变的工作负载、实现复杂的重试逻辑以及进行容错设计。考虑重组应用程序架构以更好地处理连接管理。

最佳实践

连接池

通过适当的连接池管理和监控,应用程序可以保持稳定的数据库连接,同时防止可能影响系统可靠性和性能的耗尽情况。配置适当的超时时间,并根据工作负载的特性调整池的大小。

连接池设置示例

MongoClientSettings settings = MongoClientSettings.builder() .applyToConnectionPoolSettings(builder -> builder.maxSize(10)) .applyToConnectionPoolSettings(builder -> builder.maxWaitQueueSize(2)) .applyToConnectionPoolSettings(builder -> builder.maxConnectionIdleTime(10, TimeUnit.MINUTES)) .build();

有关更多信息,请参阅使用 Amazon DocumentDB 构建弹性应用程序 — 第 1 部分:客户端配置

身份验证过载

务必根据您的工作负载使用适当的参数值来实现连接池。尽可能使用渐进连接建立技术并保持持续连接。实施适当的连接清理,确保不浪费空闲资源。

配置问题

确保您已配置了从应用程序到 Amazon DocumentDB 资源的适当路由。在传输过程中使用 TLS 进行加密并实现最低权限访问。验证您的亚马逊 DocumentDB 凭证并验证连接字符串值。