认证超时主因是mongos与shard间internalAuth配置不一致,导致SCRAM-SHA-256握手反复失败;需验证keyFile路径/权限/内容一致性、authSource显式指定及TLS耗时,避免moveChunk或心跳超时。

认证超时不是网络慢,而是 mongos 和 shard 之间反复重走 SASL 握手流程——只要 internalAuth 配置不一致、keyFile 权限不对、或 authSource 漏配,每次新建连接都会卡在 SCRAM-SHA-256 多轮交互上,最终触发 moveChunk 或心跳超时。
查 mongos 与 shard 的 keyFile 是否真正生效
别只看配置文件里写了 security.keyFile,得确认运行时加载成功且内容一致:
- 在 mongos 上执行
db.runCommand({getCmdLineOpts: 1}),检查返回中parsed.security.keyFile是否存在、路径可读、且非空字符串 - 在目标 shard primary 上执行相同命令,比对两个节点的
keyFile路径是否指向同一文件(不是“同名”,是字节级相同) - 用
ls -l /path/to/keyfile确认权限为400,属主为 mongod 进程用户;若权限是644,mongod 启动会静默忽略该 keyFile - 若任一节点返回
"keyFile" : null或字段缺失,说明该节点根本没启用 internalAuth,shard 会直接拒绝 mongos 的连接请求
验证 mongos 是否真能完成到 shard 的认证链路
不要等 sh.status() 卡住才行动,用最简命令逐层验证:
- 先确认 mongos 能连 config server:
mongo --port 27017 --eval "printjson(db.runCommand({listShards: 1}))",返回"ok" : 1才算 config 层通 - 再绕过 mongos 直连 shard primary:
mongo --host shard1-primary-host:27017 -u __system -p "$(cat /etc/mongod-keyfile)" --authenticationDatabase admin,能进 shell 说明 shard 认证本身没问题 - 最后测试 mongos 主动发起的连接:
mongo --port 27017 --eval "sh.status()" 2>&1 | grep -i "unauthorized\|timeout",出现Unauthorized表明 mongos 发出的凭据被 shard 拒绝 - 关键点:
__system用户是内部通信专用账号,必须用 keyFile 内容作密码,不能用其他 admin 用户替代
检查连接字符串里有没有漏掉 authSource
客户端驱动(PyMongo、Node.js driver、Go mongo-go-driver)若没显式指定 authSource,会在每次新建 socket 时尝试用目标库名查用户,导致认证失败后重建连接池,形成“超时→建新池→再超时”循环:
- 错误写法:
mongodb://appUser:pwd@mongos-host:27017/mydb—— 驱动默认用mydb做认证源,但用户实际在admin - 正确写法:
mongodb://appUser:pwd@mongos-host:27017/mydb?authSource=admin—— 强制认证上下文固定,连接可复用 - 特别注意:Node.js driver v4+、PyMongo v4.0+ 默认关闭跨 client 凭证缓存,即使 URL 一样,每个
MongoClient实例都独立走完整 auth 流程 - 生产环境建议加
&minPoolSize=5&maxIdleTimeMS=600000,避免频繁重建带认证开销的连接
别让 TLS 握手吃掉认证超时余量
启用 TLS 后,一次连接要完成 TCP 握手 → TLS 协商 → SCRAM 认证三阶段,任意一环慢都会压垮默认 10 秒心跳或 60 秒 moveChunk 超时:
- 用
openssl s_client -connect shard1-primary-host:27017 -tls1_2 -quiet 2>&1 | grep "handshake"测 TLS 握手耗时,超过 800ms 就需警惕 - 若 TLS 耗时正常但认证仍超时,检查 mongos 日志里是否有
"Failed to authenticate"或"No route to host"—— 后者常是认证失败后内核重置连接造成的假象 - config server 和 shard 若启用了 TLS,
--configdb参数里的地址必须和证书 SAN 中的 hostname 完全一致,否则 TLS 协商失败会拖慢整个链路
最容易被忽略的是:sh.addShard() 成功只代表 config server 记录了地址,mongos 并不会当场验证能否连上 shard;internalAuth 失配时,它会在后台无限重试并静默失败,直到你看到 moveChunk 报错或 rs.status() 显示 UNKNOWN 状态才察觉——此时往往已积压大量未路由请求。


















