官方驱动原生支持多mongos故障转移,连接字符串须用英文逗号分隔地址、参数统一置于末尾、端口显式写出;客户端启动时并发探测并选首个响应成功者,仅连接级错误触发切换;常见坑点包括DNS缓存、防火墙拦截心跳、maxPoolSize过小。

官方驱动原生支持多 mongos 故障转移,不需要加代理、不依赖 DNS 轮询,但连接字符串写错或网络配置疏漏,就会让“高可用”形同虚设。
连接字符串里多个 mongos 地址怎么写才有效
必须用英文逗号分隔,所有参数统一放在末尾,不能挂到单个地址后;端口不一致时要显式写出每个端口。
- 正确:
mongodb://mongos1:27017,mongos2:27017,mongos3:27018/mydb?ssl=true&connectTimeoutMS=5000&serverSelectionTimeoutMS=10000 - 错误:
mongodb://mongos1:27017,mongos2:27017/?ssl=true(?ssl=true只作用于mongos2) - 错误:
mongodb://mongos1,mongos2,mongos3/mydb(没端口,依赖 DNS A 记录,极易指向同一 IP)
驱动选 mongos 和切换的实际行为
客户端启动时并发探测全部地址,取第一个响应成功的建立初始连接;后续请求复用该连接,仅当发生连接级错误时才触发后台重试切换。
- 会触发切换的错误:
NetworkTimeoutError、ConnectionClosedError、NotMasterNoSlaveOk - 不会触发切换的场景:慢查询超时、业务层
maxTimeMS超时、oplog 回放延迟 -
serverSelectionTimeoutMS控制重试等待上限(PyMongo 默认 30s,Java Driver 默认 10s)
最容易被忽略的三个掉坑点
看起来连得上,其实根本没走通健康检查路径;故障转移失败往往不是驱动问题,而是基础设施层的假阳性。
- DNS 缓存未刷新:运维已下线
mongos3,但应用仍持续尝试连接旧 IP,拖慢整体发现速度 - 防火墙放行了 TCP 27017,却拦截了
isMaster心跳命令,驱动误判节点“存活”但无法转发请求 -
maxPoolSize设为 1:故障时新连接建不起来,直接报Timeout waiting for connection,而非切换
真正验证是否生效,别只 telnet mongos1 27017,得用驱动发一条真实命令,比如 db.runCommand({ping: 1}),并手动 kill 当前活跃的 mongos 进程观察是否在 serverSelectionTimeoutMS 内完成切换。











