总结:
1、外部网络原因导致的连接问题的因素很多,不过这类问题比较好排查,可以引导用户连续的ping ConnectString 即可进行诊断,不在同一个VPC的是无法ping 通的。
2、用户因素导致的连接问题需要重点说明下:
a、版本驱动的要求,MongoDB 要求用户如果使用Mongo Shell登录,则Mongo shell版本必须是3.0+,其他语言客户端版本要求参考:Driver兼容性要求,如果版本不对会报认证失败的错误,这种情况就建议用户升级Driver版本。
b、用户mongo shell连接姿势不对,Mongo shell目前常见的3种连接方式为:
1)、mongo mongodb://[Login_User]:@[ConnectString_URL]:[Instance_Port]/[Auth_Database],
例子:mongo mongodb://root:@s-2zec38d903fc0af4-pub.mongodb.rds.aliyuncs.com:3717/admin
2)、mongo [ConnectString_URL]:[Instance_port]/[Auth_Database] -u[Login_User] -p[Password],
例子:mongo dds-2ze15a12d4c7e5f41172-pub.mongodb.rds.aliyuncs.com:3717 -uroot -p
3)、mongo --host [ConnectString_URL]:[Instance_Port] --authenticationDatabase [Auth_Database] -u [Login_User] -p [Password],
例子:mongo --host dds-2ze15a12d4c7e5f41172-pub.mongodb.rds.aliyuncs.com:3717 --authenticationDatabase admin -u root -p
副本集连接方式:mongo mongodb://root:[Password]@dds-2ze15a12d4c7e5f41172-pub.mongodb.rds.aliyuncs.com:3717,dds-2ze15a12d4c7e5f42730-pub.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-6189843
这类问题比较多遇到的是用户的参数写错了,端口号不对等,另外一个比较多的用户使用误区是用户连接地址写成secondary节点地址,这种情况下用户会反馈无法读取数据,这是因为Replica sets中的secondary节点默认是不可读的,需要用户在连接中执行rs.slaveOk()或者db.getMongo().setSlaveOk()后即可正常查询,需要注意的是这是session级别的调整,新连接需要再次设置,如不想每次设置,可以参考我上面的加replicaSet的连接方式,这种情况下Driver会去判断哪个节点是Primary,并与之建连。
更详细的Connection String URI 请参考:Connection String URI Format。(生产环境一定要引导用户使用控制台上的Connect String去连接)
c、账户密码不对这个也遇到的比较多,还有一个就是登陆账户与认证数据库不匹配,MongoDB 中账户与数据库是绑定的,查看账户的详细信息可以在admin库下执行db.system.users.find();进行查看,这类情况请用户仔细核对账户、密码和认证的数据库三者是否正常。
d、用户应用程序配置的并发连接数个数过低,MongoDB实例监控看还有空闲连接,这种情况可以通过db.serverStatus().connections进行查看确认,如果current一直无法增长且值比应用端配置的连接池并发数大1则极有可能是这种情况,间接的情况就是Mongo shell可以多个客户端同时登陆,应用端缺无法新建连接进来,这种情况需要用户调大应用端连接池的并发数。
e、实例连接数打满一般都是用户的业务变化或者使用不当导致实例连接耗尽,可以通过实例的秒级监控进行确认,或者尝试执行db.serverStatus().connections进行确认,如果available值基本为0,则可以判定,通常应用端会把报:Connections refused because too many open connections的错误(连接地址不在白名单内也会报这个错误,请用户检查白名单配置),这类情况就先用户在业务端进行调整和优化,例如优化慢查询、业务限流、规格升级等。
排查步骤:
1、ping [连接地址URL] 确认网络层面是否通以及DNS是否正常解析
2、telnet [连接地址URL] [实例端口] telnet确认端口是否正常通信以及再次确认DNS是否正常解析
3、mongo shell客户端方式登录测试 用户使用的其他工具登录结果不能做为判断标准,以mongo shell登录结果为准
4、网络抓包,通过分析抓包文件定位问题点
网络抓包:
1、普通抓包,问题复现即终止
打开一个到 ECS 的 ssh 连接,并以 root 身份登录。在该窗口运行下列命令
tcpdump -i any -s 0 -w /var/tmp/rds.cap port MongoDB实例端口 or 53
2、抓一段时间包,问题复现终止
打开一个到 ECS 的 ssh 连接,并以 root 身份登录。在该窗口运行下列命令(下面的命令抓 60 分钟的包,每 5 分钟保存一个文件)
tcpdump -i any -s 0 -w /var/tmp/rds_%Y-%m-%d_%H-%M-%S.cap -G 300 -W 12 port MongoDB实例端口 and 53
3、固定大小循环抓包,问题复现终止
打开一个到 ECS 的 ssh 连接,并以 root 身份登录。在该窗口运行下列命令(下面的命令将抓包结果保存在 20 个 50 MB 文件中,循环使用)
tcpdump -i any -s 0 -w /var/tmp/rds.cap -C 50 -W 20 port MongoDB实例端口 or 53