资讯动态

Nacos 2.3 接入达梦 DM8 实战:数据源、建表脚本与方言避坑

发布时间:2026/10/26 18:28:48 来源:尧图企业网站定制
简介面向需要在国产数据库环境中落地注册配置中心的开发与运维人员这份 nacos 适配达梦数据源整合包提供可直接运行的 Windows、Linux 版本并附带可二次修改、自行编译的源码用于解决 Nacos 默认数据源与达梦不兼容时的部署和改造问题。压缩包共 92 个文件约 297.51MB涵盖配置、日志、集群元数据、启动脚本、SQL 初始化文件及构建产物等既有已编译服务端目录也保留可导入 IDEA 调整的工程内容便于按需替换配置或重新打包。已有 895 人学习说明该方案在国产化迁移场景中具有一定参考价值。读者可快速搭建验证环境导入达梦初始化脚本并结合配置项与脚本排查数据源连接、集群启动和配置推送等问题减少从零改造的时间。1. 从一次换库翻车说起Nacos 2.3 接达梦 DM8 到底卡在哪某次信创改造要把一套微服务的注册配置中心从 MySQL 挪到达梦 DM8。当时判断很朴素换驱动、改 URL、导脚本半小时的事。结果 Nacos 起来了控制台能登录配置也能发一周后才发现数据全写进了内嵌 Derby达梦那边一张表都没动。这就是 nacos 达梦 组合最坑的地方——它不报错它只是静默地用另一套存储。中间还接连踩了建表脚本里ON UPDATE CURRENT_TIMESTAMP、分页LIMIT ?,?、实例大小写敏感三个雷。下面按实际落地顺序走一遍版本怎么挑、达梦侧参数和脚本怎么改、Nacos 侧驱动和方言怎么收口、报错怎么查最后怎么确认数据真的落进达梦。2. 版本盘点与环境准备Nacos、DM8 与 DmJdbcDriver18 的搭配清单动手之前先把三条链路分清楚Nacos 服务端自身的 JDK、达梦实例的 JDBC 驱动、以及 Nacos 访问数据库的那层数据源实现。这三者版本错位表现出来往往是“启动成功但行为不对”排查起来非常耗时间。我一般会先在纸上把版本写死再开工避免一边装一边试。2.1 三条链路分别对齐什么版本Nacos 2.x 的服务端编译目标是 JDK 8运行在 JDK 8 和 JDK 11 上都稳JDK 17 不是不能跑但一些依赖的反射行为会变不是这次换库要解决的问题别在这上面加变量。达梦这边DM8 的 JDBC 驱动有好几个文件名DmJdbcDriver18.jar对应 JDK 1.8 及以上驱动类是dm.jdbc.driver.DmDriver这个类名必须和配置文件里写的一字不差写错就是No suitable driver。达梦服务端版本用 8.1.x 系列即可重点不在小版本号而在实例初始化时的那几个参数第 3 章会展开。Nacos 版本是这套组合里最需要做取舍的一项。2.0.x 和 2.1.x 用spring.datasource.platform声明数据源平台2.2.0 起改成spring.sql.init.platform同时把 MySQL 驱动从主包里摘出去改由plugins/mysql/目录外挂。这个变化对达梦适配是利好——驱动外置意味着我们塞达梦的 jar 进去就能被加载不用重新打 fat jar。所以只要条件允许我建议直接上 2.2.x 或 2.3.x别在 2.1 上折腾。组件建议版本关键说明Nacos2.2.3 / 2.3.x2.2 起数据源插件化、JDBC 驱动外置JDK8 或 11与 Nacos 编译目标一致别引入 17DM88.1.x需要 MySQL 兼容模式JDBC 驱动DmJdbcDriver18.jar驱动类dm.jdbc.driver.DmDriver客户端工具disql灌 schema、核对数据都靠它另外要留意一个容易被忽略的差异Nacos 2.2 之后nacos-datasource-plugin这一层把 SQL 方言抽成了 SPI默认实现只有 MySQL 一套。也就是说Nacos 发出的 SQL 天然是按 MySQL 语法写的达梦能不能直接接住取决于兼容模式覆盖到什么程度。这个判断直接决定后面要不要写插件代码。2.2 数据源到底走哪条路先想清楚再配Nacos 单机启动时如果没有配外置数据源会退回内嵌 Derby数据落在${NACOS_HOME}/data/derby-data下。这个兜底逻辑是好事也是最大的坑配置写错它不会启动失败只是默默用 Derby。判断依据只有一个——db.num是否大于 0 且db.url.0是否存在两个条件同时满足才会构建外置数据源。所以配置阶段的核心不是“把 URL 写对”而是“让 Nacos 相信你要用外置库”。常见做法是把这几行一次性写全不要留注释状态的分号试探# 平台声明2.2.0 起用 spring.sql.init.platform老版本是 spring.datasource.platform spring.sql.init.platformmysql # 库数量必须 1否则直接走内嵌 Derby db.num1 # 第 0 个库的连接串schema 指定到达梦用户 db.url.0jdbc:dm://10.0.0.21:5236?schemaNACOSuseUnicodetruecharacterEncodingUTF-8 db.user.0NACOS db.password.0Nacos_2024#dm # 驱动类必须显式改默认值还是 com.mysql.cj.jdbc.Driver db.pool.config.driverClassNamedm.jdbc.driver.DmDriverdb.num这一行看着多余实际是最常被删掉的一行。有人在精简配置时觉得“只有一个库写它干嘛”删完重启日志一切正常Derby 目录又冒出来了。db.pool.config.前缀是 Nacos 对连接池属性的透传后面的名字按连接池本身的属性名写driverClassName、maximumPoolSize、connectionTimeout都在这个命名空间下。2.3 开工前的资源核对数据库连接数是最容易在上线后炸的一项。达梦实例的MAX_SESSIONS默认值不大而 Nacos 集群每个节点都会起一个连接池再加上运维工具、监控采集的会话很容易顶到上限。我一般按“节点数 × 池上限 50”估一个值出来再回头调实例参数。内存方面单机验证给 2G 就够startup.sh -m standalone默认堆不大但达梦侧如果和 Nacos 同机注意别把两边堆加起来把机器吃满。还有一项准备是备份。改application.properties之前先复制一份带日期后缀的副本这是整套流程里唯一的后悔药。后面任何一步走不通把副本盖回去、重启至少能回到一个已知可用的状态不用在几十行配置里靠记忆还原。3. 达梦侧的准备工作实例参数、表空间与建表脚本改造这一章是整套适配里最花时间、也最容易返工的部分。Nacos 的建表脚本是给 MySQL 写的直接扔进达梦能执行一半然后在中途某条语句上报语法错误前面的表已经建了后面的没建最后得到半个 schema。所以脚本必须先改后灌不要边灌边改。3.1 两个初始化参数决定了后面所有事达梦实例有两个参数装完再改代价很大必须在建库那一步就定下来。第一个是COMPATIBLE_MODE取值 3 表示 MySQL 兼容模式。开了之后一部分 MySQL 语法和函数能被识别Nacos 发出的 SQL 命中率会高很多。这个参数可以通过系统过程修改并重启生效-- scope 传 2 表示同时写进 dm.ini重启实例后生效 SP_SET_PARA_VALUE(2, COMPATIBLE_MODE, 3); -- 顺手把会话上限提上去避免后面连接池打满 SP_SET_PARA_VALUE(2, MAX_SESSIONS, 500);第二个是CASE_SENSITIVE控制标识符大小写是否敏感默认是敏感的。达梦在敏感模式下会把不加引号的表名、列名统一按大写处理而 Nacos 的 SQL 全是小写裸名结果就是一堆“无效的列名”。这个参数不能在实例建好后修改只能在初始化实例时指定为不敏感。我见过最惨的一种情况是实例已经跑着别的业务只能新建一个实例专门给 Nacos 用。修改完参数用下面这条语句确认落地情况别只信命令没报错SELECT PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME IN (COMPATIBLE_MODE, CASE_SENSITIVE, MAX_SESSIONS);V$DM_INI是达梦的实例参数视图PARA_VALUE是字符串类型看到3和N才算真的生效。如果CASE_SENSITIVE还是Y后面的建表和查询都会反复出问题不如现在就停下来重建实例。3.2 建表空间与业务用户不建议用 SYSDBA 跑业务表权限太大出了问题也不好定位。单独建一个表空间和用户把这套 Nacos 的表全部收在里面。-- 表空间初始 512M按 64M 递增上限 10G CREATE TABLESPACE NACOS DATAFILE /dm/data/DAMENG/NACOS01.DBF SIZE 512 AUTOEXTEND ON NEXT 64 MAXSIZE 10240; -- 业务用户默认表空间指向 NACOS CREATE USER NACOS IDENTIFIED BY Nacos_2024#dm DEFAULT TABLESPACE NACOS; -- 验证环境直接给 DBA生产按需授予 CREATE TABLE / CREATE SESSION 等权限 GRANT DBA TO NACOS;这里给DBA是为了验证阶段省事能跑通之后再逐条收权限。表空间的数据文件路径按实际安装目录改AUTOEXTEND ON一定要开Nacos 的历史配置表his_config_info增长比想象中快磁盘不够时表空间写满会直接导致发布失败。3.3 mysql-schema.sql 的逐条改法原始脚本在 Nacos 发行包的conf/mysql-schema.sql先解压取出来# 从发行包里单独取出建表脚本避免整包解压 unzip -o nacos-server-2.3.2.zip nacos/conf/mysql-schema.sql -d /tmp/nacos-src cp /tmp/nacos-src/nacos/conf/mysql-schema.sql /tmp/dm-schema.sql # 先把所有 MySQL 专有写法列出来逐条确认改没改 grep -nE ENGINE|AUTO_INCREMENT|ON UPDATE CURRENT_TIMESTAMP|UNIQUE KEY| KEY |bigint\(|tinyint\(|longtext /tmp/dm-schema.sql改造对照关系如下这张表我一般存成便签每换一次库都要过一遍MySQL 写法达梦写法说明bigint(20)/tinyint(4)BIGINT/TINYINT去掉显示宽度达梦不认括号里的数字AUTO_INCREMENTIDENTITY(1,1)放在列类型后面自增起点和步长longtext/textCLOB配置内容字段必须用大对象类型datetimeTIMESTAMP时间精度按需加(6)ON UPDATE CURRENT_TIMESTAMP直接删掉达梦不支持靠应用层显式更新时间ENGINEInnoDB DEFAULT CHARSETutf8直接删掉表尾整段去掉UNIQUE KEY uk_x (a,b)CONSTRAINT uk_x UNIQUE (a,b)内联索引改成表级约束KEY idx_x (a)单独CREATE INDEX idx_x ON t(a);普通索引从建表语句里拆出来ON UPDATE CURRENT_TIMESTAMP删掉之后要确认一件事Nacos 更新配置时是否自己写了gmt_modified。大部分更新语句是显式传时间参数的但也有少数依赖数据库自动更新。稳妥的做法是先跑通然后连续发布两次配置用 disql 看gmt_modified有没有变化没变就说明这条链路依赖了数据库特性得补一个触发器或者改 SQL。列名关键字的问题也要单独过一遍。type、level、role、comment这几个词在达梦里属于关键字直接当列名用会报语法错误。两种处理建表时给列名统一加双引号配合实例的大小写不敏感能对上 Nacos 发出的裸名如果加引号后仍然报无效列名就说明必须改名改完把对应的 Mapper 字段名一起改。改完的脚本用 disql 灌进去用 heredoc 的方式避免 shell 把反引号当命令替换disql NACOS/Nacos_2024#dm10.0.0.21:5236 EOF set echo off start /tmp/dm-schema.sql exit EOF灌完立刻核对表数量别等 Nacos 启动时才报错-- 业务用户下应该能看到十几张表 SELECT COUNT(*) FROM USER_TABLES; -- 单独确认配置主表结构完整 SELECT COLUMN_NAME, DATA_TYPE FROM USER_TAB_COLUMNS WHERE TABLE_NAME CONFIG_INFO ORDER BY COLUMN_ID;USER_TABLES和USER_TAB_COLUMNS是达梦的数据字典视图第二条能直接看出content字段是不是变成了CLOB、自增列有没有加上IDENTITY。这一步花五分钟比后面在启动日志里猜半小时划算。4. Nacos 侧接入配置驱动落位、数据源参数与方言收口达梦那边准备好之后Nacos 侧的活其实不多但每一步都有个“配错了也不报错”的陷阱。顺序上我习惯先解决驱动能不能加载再解决连接串对不对最后才处理 SQL 方言——前面没通之前改 SQL 是白费功夫。4.1 驱动 jar 放在哪才生效Nacos 2.2.0 之后 JDBC 驱动不再打进主包而是从${NACOS_HOME}/plugins/下的子目录加载。达梦的驱动直接从安装目录拷过去就行# 达梦驱动默认在安装目录的 drivers/jdbc 下 ls /opt/dmdbms/drivers/jdbc/DmJdbcDriver18.jar # 放到 Nacos 约定的外挂驱动目录注意是 plugins/mysql不是 plugins/dm mkdir -p ${NACOS_HOME}/plugins/mysql cp /opt/dmdbms/drivers/jdbc/DmJdbcDriver18.jar ${NACOS_HOME}/plugins/mysql/ # 确认启动脚本把这个目录拼进了类加载路径 grep -n plugins/mysql ${NACOS_HOME}/bin/startup.sh目录名mysql看着别扭但这是 Nacos 发行包固定的约定放plugins/dm不会被扫描到。如果grep没有任何输出说明这个版本的启动脚本没有拼这段路径手动在JAVA_OPT里补一行-Dloader.path${BASE_DIR}/plugins/mysql。补完用sh bin/startup.sh -m standalone启动一次日志里出现驱动相关异常就说明类没加载到先解决这个再看别的。4.2 application.properties 的六行关键配置配置文件的改动集中在数据源这一段其余保持默认。除了 2.2 小节那几行连接信息连接池参数也建议显式写出来默认值在不同版本间有差异# 连接池上限按达梦 MAX_SESSIONS 反推集群节点数乘以它要留余量 db.pool.config.maximumPoolSize20 db.pool.config.minimumIdle5 # 拿不到连接等多久默认 30 秒内网可以适当缩短便于快速暴露问题 db.pool.config.connectionTimeout30000 # 连接空闲校验防止达梦侧把长时间空闲的会话掐掉后拿到死连接 db.pool.config.validationTimeout10000 db.pool.config.idleTimeout600000 db.pool.config.maxLifetime1800000maxLifetime比达梦侧会话超时时间短是一套组合拳里容易被忽略的一环。数据库侧主动断开空闲连接时连接池如果还认为连接有效业务侧就会拿到一个已经断掉的连接报错信息通常是“连接已关闭”之类非常难定位。做法就是让连接池先于数据库回收连接。还有一个判断要提前说清楚spring.sql.init.platformmysql这个键在 Nacos 里的作用是声明初始化脚本的平台配合 Spring 的脚本初始化机制。生产环境不要指望它自动建表表还是手动用 disql 灌。它的价值在于让配置和版本对齐少一个变量。4.3 方言收口先跑通再改 SQLNacos 的 SQL 是按 MySQL 写的开了兼容模式之后大部分能直接执行剩下的是少数几类。我一般按“先跑、看报错、再改”的顺序而不是一上来就写一套方言实现。常见的三类差异按出现频率排第一类是分页。MySQL 写LIMIT offset, size达梦兼容模式不一定接受这种带逗号的形式报错信息通常是Syntax error near ,。改成LIMIT size OFFSET offset就能过。第二类是INSERT ... ON DUPLICATE KEY UPDATE这类 MySQL 专有写法达梦要用MERGE INTO改写。这类语句数量不多但一旦命中就是启动期的功能不可用。第三类是聚合函数GROUP_CONCAT在达梦没有同名实现需要换成对应的字符串聚合函数。如果确实需要改 SQLNacos 2.2 之后提供了 SPI 扩展点把方言实现注册进去即可。做法是在自己的工程里放一个 SPI 声明文件内容是自定义实现类的全限定名# 文件路径 src/main/resources/META-INF/services/com.alibaba.nacos.plugin.datasource.MapperManager # 内容一行指向你自己的方言实现类 com.example.nacos.dm.DmMapperManagerImpl自定义实现的做法是继承默认的 MySQL 实现只覆盖报错的那几个方法其余全部沿用父类。方法签名照抄父类不要自己发明参数顺序// 只覆盖分页方法其余 SQL 全部沿用父类的 MySQL 实现 public class DmConfigInfoMapper extends ConfigInfoMapper { Override public String findConfigInfoLike4PageFetchRows(int startRow, int pageSize) { // 达梦用 LIMIT size OFFSET offset避免 MySQL 的 LIMIT a,b 语法 return SELECT id, data_id, group_id, tenant_id, app_name, content, md5 FROM config_info WHERE 11 LIMIT pageSize OFFSET startRow; } }方法名以你引入的插件版本为准编译不过就去 IDE 里看父类定义别硬改。改完之后把插件 jar 放进${NACOS_HOME}/plugins/对应目录重启验证。这套做法的好处是改动面极小坏处是多一个需要维护的 jar所以能不改尽量不改先用兼容模式扛住。4.4 启动与第一轮确认启动命令本身没变化单机模式加-m standalonecd ${NACOS_HOME} sh bin/startup.sh -m standalone # 启动日志重点看有没有 use external storage 字样 tail -f logs/start.out启动完成后第一件事不是开控制台而是看数据目录# 目录里出现 derby-data 就说明还在用内嵌库配置没生效 ls -l ${NACOS_HOME}/data这个检查看着土但它是整套流程里最快的是非判断。只要data/derby-data没出现就说明 Nacos 确实走了外置数据源后面再去核对表里的数据才有意义。5. 排查清单启动报错、连接超时与静默回退的五条踩坑记录这套组合的问题有个共同点大部分不报“致命错误”而是表现为功能静默失效。下面五条是我在不同环境里真实遇到过的按现象、原因、解决三段记录遇到新问题时可以先对照一遍。5.1 五条踩坑记录第一控制台能登录、配置能发布但达梦的表是空的。现象是data/derby-data目录被创建用 disql 查config_info只有 0 行。原因是外置数据源没构建起来最典型的是db.num没写或者写成 0其次是db.url.0被注释掉了还有一种是把配置写到了cluster.conf里但启动用了单机模式。解决是把db.num1和db.url.0两行补全重启后看启动日志里是否出现使用外置存储的提示再ls data/确认 Derby 目录不再生成。第二启动直接抛No suitable driver found for jdbc:dm://...。现象是 Nacos 起不来日志里一大段连接异常。原因有两个驱动 jar 没放进plugins/mysql/或者db.pool.config.driverClassName没改还是默认的 MySQL 驱动类。解决是确认 jar 在这个目录下、启动脚本把它拼进了loader.path同时把驱动类显式写成dm.jdbc.driver.DmDriver三个条件缺一不可。第三SQL 报“无效的列名”。现象是启动时某条查询报错或者发布配置时报列不存在。原因是实例的大小写敏感参数是Y达梦把裸列名当大写处理和 Nacos 传的小写对不上也可能是列名撞了达梦关键字。解决办法是先确认CASE_SENSITIVE为N实例改不了就只能重建关键字冲突就给列名加双引号仍不行就改名并同步改 Mapper。第四建表脚本执行到一半中断。现象是表建了一部分后面的语句报Syntax error near ON UPDATE或ENGINE。原因是脚本没改干净MySQL 的表尾选项漏了。解决办法是灌之前先跑一遍 grep把ENGINE、AUTO_INCREMENT、ON UPDATE CURRENT_TIMESTAMP、bigint(这几类全部列出来逐条确认改完再灌。已经建了一半的表先删掉重来不要在半成品 schema 上继续。第五运行一段时间后报连接池超时Connection is not available, request timed out。现象本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑