现象很别扭,说出来甚至有点"玄学":
最要命的是没有任何报错线索:数据库侧日志干净,集群侧日志干净,客户端也没有明确的错误码。故障发生在请求到达数据库之前。
面对"连不上"这种宽泛的现象,不要一头扎进集群日志。用两个正交动作快速缩小范围:
| 动作 | 结果 | 结论 |
|---|---|---|
| 重启数据库服务器 | 连接恢复 | 服务端能自愈,集群没问题 |
| 重启应用程序 | 连接失败 | 问题在客户端随应用启动才加载的东西 |
"随应用启动重新加载"的东西就那么几样:配置文件、驱动版本、连接池参数。顺着这条线,把 dm_svc.conf 与部署模板逐键比对,问题就露出来了——服务名段下写的是:
SWITCH_TIME=(300) # 正确应为 SWITCH_TIMES
少写了末尾的 s。 改回去,反复重启应用,再没复现。
原因有三层,一层比一层关键:
第一层:解析器静默忽略非法键名。
dm_svc.conf 的解析器遇到不认识的键名,不报错、不写日志,直接跳过。所以这份"错误"的配置文件在任何人眼里都是格式完好的——这是这类问题最难发现的地方。
第二层:丢掉的是连接重试兜底。
SWITCH_TIMES(重试次数)和 SWITCH_INTERVAL(重试间隔,毫秒)负责在连接未即时成功时继续重试。这两个参数一旦缺失,驱动就失去了兜底能力:首次连接不成功就直接失败。
第三层:所以现象才"看运气"。
重启服务器的场景下,集群已切换完成并稳定,应用随后连接一次就命中,看起来没问题;而重启应用时如果赶上主备状态与解析结果不一致的窗口,没有重试就直接崩溃。一个"随机"现象,本质是兜底机制缺失被时机放大。
服务端为什么毫无痕迹?因为失败卡在客户端解析和服务名寻址阶段,请求根本没发出去。
找到配置文件(Linux /etc/dm_svc.conf;Windows 64 位 %SystemRoot%\system32\dm_svc.conf,32 位进程则在 SysWOW64),改成正确键名,重启应用:
[DW1]
CLUSTER=(DW)
LOGIN_MODE=(1)
SWITCH_TIMES=(300)
SWITCH_INTERVAL=(200)
如果配置文件不便修改,也可以在连接串内联参数——但参数名必须用驼峰写法,否则同样被忽略:
jdbc:dm://DW1?loginMode=1&switchTimes=300&switchInterval=200
这个风险的本质:不是"配置写错了",而是"写错了没人告诉你"。静默忽略的设计让配置类故障极其隐蔽,必须靠主动核对而非肉眼扫读来兜住。
dm_svc.conf 连接失败六查清单(建议直接抄进运维手册):
SWITCH_TIMES 是最高频错项,另有 SWITCH_INTERVAL、AUTO_RECONNECT;IP:PORT 是否写全所有节点(只写当前主库,切换后必挂);/etc;Win64 system32;32 位 SysWOW64);/etc/hosts 或 DNS 能否解析;两条经验:
同类坑不限于 dm_svc.conf。达梦的
dm.ini、dmmal.ini、dmwatcher.ini、dmarch.ini都存在键名拼错被静默忽略的机制。凡是 ini 类配置,改完都值得跑一次键名核对。
文章
阅读量
获赞
