连接访问与网络

本文旨在帮助您解决连接 MongoDB 实例时遇到的问题。建议优先查阅常见报错章节,以快速定位并解决问题;如果未找到匹配的错误信息,可参考排查步骤,自主诊断和解决连接问题。

连接问题排查步骤

步骤一:网络连接

排查方法

通过以下命令测试到达MongoDB实例的网络是否通畅。

  • ping <域名>,例如ping dds-xxxx.mongodb.rds.aliyuncs.com

    image

    图中示例表示客户端与MongoDB实例之间网络连通。

  • telnet <域名> <端口号>,例如telnet dds-xxxx.mongodb.rds.aliyuncs.com 3717

    测试端口图中示例表示可以正常解析该域名地址,且3717端口可正常通信。

核查清单

如果网络测试不通,请通过以下方式排查问题及解决。

检查实例状态。实例的状态需为运行中

检查白名单设置。需要将客户端IP地址添加到云数据库MongoDB实例的白名单中。

  • 排查方法:

    • (推荐)使用云数据库MongoDB的连接诊断功能,检测IP地址是否连通,检测及解决方法,请参见连接诊断连接诊断

    • 请在数据库的白名单中临时添加0.0.0.0/0,如果设置后可以正常访问,说明是白名单设置存在问题。

      重要

      0.0.0.0/0表示允许任何设备访问云数据库MongoDB实例,请谨慎使用,测试完成后请及时修改。

  • 解决方法:

    将正确的客户端IP地址添加到云数据库MongoDB实例的白名单中。获取本地公网IP地址的方法,请参见常见问题

检查网络环境与实例连接地址。云数据库MongoDB支持私网和公网两种连接方式,不同网络环境需使用不同的连接地址。

您可以登录MongoDB管理控制台,在数据库连接页面查看云数据库MongoDB实例的连接地址。

步骤二:授权与身份验证

确认账户名与密码,并检查密码中是否包含特殊字符。

  • 确认提供的账户名与密码信息正确。

  • 修改密码。如果您需要修改密码,请参见重置密码

    如果您通过DMS连接云数据库MongoDB实例后,修改了密码,请在DMS数据管理服务页面,右击目标实例,编辑实例重新登录。

  • 特殊字符。通过Mongo Shell或程序代码连接云数据库MongoDB实例时,如果连接串中的账号密码包含特殊字符!@#$%^&*()_+=,需要转义处理。解决方法,请参见如何解决连接串中账号密码包含特殊字符导致失败的问题?

检查鉴权数据库。数据库账号必须在所属的数据库下验证,才能鉴权成功。

检查实例连接地址。副本集实例,并且需要执行写操作,推荐使用ConnectionStringURI地址连接实例。

  • 现象:没有改变连接地址,实例突然无法连接。

  • 原因:仅主节点可以执行写操作。如果您的业务之前通过主节点(Primary节点)的地址连接,副本集实例主备切换后,实际连接的节点角色变成了从节点(Secondary节点),写入会失败。

  • 解决方法

    请为业务设计重连机制和异常处理能力,连接闪断后可自动重连,保障业务稳定运行。

步骤三:其他问题核查

检查实例性能是否满足业务需求。

  • 连接数。检查实例的连接数是否达到上限。

  • 其他资源运行情况

    • 排查方法:通过节点监控查看常用资源(例如CPU使用率和内存使用率)的运行情况,确认实例规格大小是否满足业务需求。

    • 解决方法:如果实例规格过小,但负载较高,可在业务低峰期变更实例配置

检查第三方工具。

当第三方工具(如Navicat、Compass等工具)无法连接云数据库MongoDB实例时,可能是实例设置或者第三方工具设置不正确导致。建议您通过以下步骤排查:

  1. 使用Mongo Shell测试。

    建议通过Mongo Shell工具连接实例的高可用连接串(ConnectionStringURI地址)连接实例测试。

  2. 根据测试结果排查问题。

    • 连接成功:表示实例本身可访问,可能是第三方工具设置不正确。请根据您实际使用的工具,具体排查工具的各种设置。

    • 连接失败:若Mongo Shell无法连接,可能是实例设置不正确。请参照本文排查网络连接、授权及身份验证等其他设置。

常见报错

错误信息

报错原因及解决方法

network error while attempting to run command 'isMaster' on host 'dds-xxxx.mongodb.rds.aliyuncs.com:3717' :exception: connect failed

  • Timed out after 3000ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. exception=(com.mongodb.MongoSocketReadException: Prematurely reached end of stream)

  • Socket recv() errno:54 Connection reset by peer x.x.x.x:27017

可能该实例的连接数已经达到上限,无法为新的连接请求建立连接。

解决方法

  1. 检查连接数是否耗尽:如何查询连接数?

  2. 优化连接使用:如何解决实例连接数满的问题?

MongoDB.Driver.MongoWaitQueueFullException: The wait queue for acquiring a connection to server xxx is full.

MongoDB 驱动程序的等待队列已满,可能由于连接池设置较小或出现高并发请求等原因导致,从而无法提供可用连接。

解决方法

  1. 建议您优先检查对应报错程序的连接池配置,例如确保设置了合理的连接池大小,详情请参见如何限制终端连接数?

  2. 若程序侧调整后问题依然存在,您可检查MongoDB实例侧的连接数是否耗尽,请参见:

    1. 如何查询连接数?

    2. 如何解决实例连接数满的问题?

(TooManyLogicalSessions) Unable to add session into the cache because the number of active sessions is too high.

并发连接过多时,可能会耗尽可用会话。

解决方法

  1. 排查因连接数耗尽导致连接失败的问题。

    1. 如何查询连接数?

    2. 如何解决实例连接数满的问题?

  2. 如果连接数未发现异常,排查实例其他性能是否无法满足业务需求。

    1. 通过节点监控查看常用资源(例如CPU使用率和内存使用率)的运行情况,确认实例规格大小是否满足业务需求。

    2. 如果实例规格过小,但负载较高,可在业务低峰期变更实例配置

  • getaddrinfo failed.

  • No suitable servers found (`serverSelectionTryOnce` set).

请检查实例连接地址是否正确,连接地址说明,请参见:

  • Failed to connect to 10.*.*.8:3717 after 5000 milliseconds, giving up.Error: couldn't connect to server 10.*.*.8:3717 (10.*.*.8), connection attempt failed

  • pymongo.errors.ServerSelectionTimeoutError: dds-xxxx.mongodb.rds.aliyuncs.com:3717: [Errno 113] No route to host,dds-xxxx.mongodb.rds.aliyuncs.com:3717

  • InvalidInstanceId.NotFound: The instance not in current vpc.

云服务器ECS实例通过私网连接云数据库MongoDB失败。

解决方法

  1. 检查白名单设置。确保云服务器ECS实例的私网IP地址添加到云数据库MongoDB实例的白名单

  2. 确保ECS实例与MongoDB实例网络互通。

    ECSMongoDB实例在同一个专有网络中(VPC ID相同),可直接通过私网连接。跨VPC时,可参考以下方式调整。

org.springframework.data.mongodb.UncategorizedMongoDbException: Timeout while receiving message; nested exception is com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message

  • "errmsg": "not master", "code": 10107, "codeName": "NotMaster"

  • "errmsg": "not master", "code": 10107, "codeName": "NotWritablePrimary"

  • Time out after 30000ms while waiting for a server that matches writableServerSelector.

  • Command failed with error 10107 (NotWritablePrimary): 'not primary' on server xxx.

  • Explain's child command cannot run on this node. Are you explaining a write command on a secondary?

  • not master and slaveOk=false.

  • MongoNotPrimaryException: Command failed with error 10107 (NotMaster): 'not master' on server xxx.

  • reason: TopologyDescription { type: 'ReplicaSetNoPrimary',...}

当前写入数据的节点不是主节点(Primary节点)。

原因:仅主节点可以执行写操作。如果您的业务之前通过主节点(Primary节点)的地址连接,副本集实例主备切换后,实际连接的节点角色变成了从节点(Secondary节点),写入会失败。

解决方法

请为业务设计重连机制和异常处理能力,连接闪断后可自动重连,保障业务稳定运行。

[Unauthorized] cloud instance error, disk locked, plz check and upgrade your disk quota,

磁盘满导致实例锁定。

解决方法解决因磁盘空间耗尽导致的锁定或无法写入问题

(AuthenticationFailed) Authentication failed.

  • !xxx@dds-xxx.mongodb.rds.aliyuncs.com: event not found

数据库账号的密码中包含特殊字符!@#$%^&*()_+=

解决方法如何解决连接串中账号密码包含特殊字符导致失败的问题?

error getting cluster ID: (CommandNotFound) replSetGetConfig is forbidden by cloud provider for security reason

云数据库MongoDB不支持replSetGetConfig命令。更多信息,请参见云数据库MongoDB版支持及限制哪些命令?

常见问题

如何查询连接数?

根据您购买的MongoDB实例规格不同,最大连接数也不同,详情请参见实例规格

说明

最大连接数是指实例中每个节点的最大连接数,例如您购买了12G规格的三节点副本集实例,那么该实例的Primary节点和Secondary节点的最大连接数均为500,Hidden节点由于其架构特殊性,不对外提供服务。

控制台查看

  1. 访问MongoDB副本集实例列表MongoDB分片集群实例列表,在上方选择地域,然后单击目标实例ID。

  2. 在目标实例页面的左侧导航栏,单击监控信息

  3. 监控信息页面,查看实例当前的连接数信息。

    实例为分片集群实例时,您需要在页面右上角选择业务当前使用的Mongos节点。

命令查看

  1. 通过Mongo Shell连接实例

  2. 查看连接数。

    执行命令db.serverStatus().connections

    mgset-123456:PRIMARY> db.serverStatus().connections
    {
            "current" : 1,
            "available" : 999,
            "internal_current" : 10,
            "internal_available" : 990,
            "totalCreated" : 632
    }             

    参数说明:

    • "current" :当前已经建立的连接数。

    • "available" :当前可用的连接数。

  3. 查询当前连接来源。

    1. 切换至admin数据库。

      use admin
    2. 执行命令db.runCommand({currentOp: 1, $all: true})

      mgset-123456:PRIMARY> db.runCommand({currentOp: 1, $all:[{"active" : true}]})                    

    通过分析命令的输出结果,您可以查询每个连接对应的来源IP地址,从而得出各终端与MongoDB实例分别建立了多少连接。更多详情请参见官方文档

如何限制终端连接数?

通过Connection String URI连接数据库时,在URI末尾加上&maxPoolSize=<integer>即可设置连接池的连接数。Mongo Shell连接示例(设置连接数为10),数据库账号为test,所属数据库为admin:

mongo "mongodb://test:****@dds-bp19f409d7512****-pub.mongodb.rds.aliyuncs.com:3717,dds-bp19f409d7512****-pub.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-6108****&maxPoolSize=10"
说明

关于不同语言的客户端如何限制连接池的数量,请参见MongoDB官网的API文档

如何解决实例连接数满的问题?

您可以通过重启实例、组件或节点来临时释放所有的连接。

重要

重启实例的操作会将实例的节点进行轮转重启,每个节点会有30秒左右的闪断,如果集合的数量较多(超过1万),闪断时间也会随之变长,重启前请做好业务安排并确保应用有重连机制。

为避免再次出现该问题,重启后建议您参考下述方法进行调整:

如何解决连接串中账号密码包含特殊字符导致失败的问题?

通过Mongo Shell或程序代码连接云数据库MongoDB实例时,连接串中的账号密码包含特殊字符!@#$%^&*()_+=,这些特殊字符在连接时无法被识别,导致实例连接失败。

解决方法:您需要在连接串中对特殊字符进行转义处理,转义规则如下:

! : %21
@ : %40
# : %23
$ : %24
% : %25
^ : %5e
& : %26
* : %2a
( : %28
) : %29
_ : %5f
+ : %2b
= : %3d

示例:密码为ab@#c时,在连接串中对特殊字符进行转义处理,密码对应为ab%40%23c

如何在连接中指定鉴权数据库?

鉴权数据库用于存储数据库账号和密码,数据库账号必须在所属的数据库下验证,才能鉴权成功。

假设账号和密码都是test,test账号属于testdb数据库。

高可用地址

当您使用ConnectionStringURI地址、ReadOnly ConnectionStringURI高可用地址连接数据库时,需要设置authSource参数指定数据库账号所属的数据库,如果不配置该参数,<database>会作为鉴权数据库。

示例如下:

  • test账号在testdb数据库鉴权成功后,实例进入<database>数据库。

mongo "mongodb://test:test@<host1>:<port1>,<host2>:<port2>,...,<hostN>:<portN>/<database>?replicaSet=<replicaSet_value>&authSource=testdb"
  • test账号在testdb数据库鉴权成功后,实例进入testdb数据库。

mongo "mongodb://test:test@<host1>:<port1>,<host2>:<port2>,...,<hostN>:<portN>/testdb?replicaSet=<replicaSet_value>"

单节点地址

可使用如下命令登录:

mongo --host $myhost --port $myport -u test -p test --authenticationDatabase testdb

或者

    mongo --host $myhost --port $myport
    mongo> use testdb
    mongo> db.auth("test", "test")

关于连接地址的参数说明,请参见副本集实例连接说明分片集群实例连接说明

如何通过DMS登录MongoDB数据库?

云数据库MongoDB支持哪些语言的客户端进行连接?

云数据库MongoDB完全兼容官方MongoDB。即官方MongoDB支持的客户端,云数据库MongoDB全部支持。

例如:C、C++、C#、Java、Node.js、Python、PHP、Perl等语言,详情请参见官方链接

程序代码示例,请参见:

说明

为确保连接云数据库MongoDB时能够正常鉴权,请使用MongoDB 3.0以上版本的Driver。

云数据库MongoDB是否支持公网访问?

支持。具体操作,请参见本地客户端通过公网连接MongoDB

云数据库MongoDB版是否支持免密访问?

云数据库MongoDB版已不支持开启VPC网络下的免密访问。

已开启免密访问的实例可以关闭该功能,关闭后无法重新开启。关闭免密访问的具体操作,请参见关闭私网免密访问

Windows系统安装和使用Mongo Shell

  • 安装Mongo Shell。访问MongoDB Shell 下载页面,按照页面提示下载并安装。

  • 使用Mongo Shell。

    • 打开cmd命令窗口。

    • 连接MongoDB实例。

      示例:

      mongosh "mongodb://test:****@dds-bp19f409d7512****.mongodb.rds.aliyuncs.com:3717,dds-bp19f409d7512****.mongodb.rds.aliyuncs.com:3717,dds-bp19f409d7512****.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-6108****"    

      关于连接地址的参数说明,请参见副本集实例连接说明分片集群实例连接说明

常见连接场景