简介:这份资源面向需要在分布式架构中将Nacos与达梦数据库打通的开发与运维人员,聚焦服务发现、配置管理、健康检查等场景下的国产数据库适配问题。包内共17个文件,以sql建表脚本、conf配置样例、sh与cmd启停脚本、xml与properties配置文件为主,另含jar驱动包及license、notice等说明文件,压缩包约150.26MB,覆盖从驱动加载、连接池配置到服务注册与配置动态更新的关键环节。已有2656人学习下载,说明国产化替代场景下此类适配需求较为集中。读者可借助其中的达梦建表脚本、配置模板与启动脚本,快速搭建Nacos对接达梦的运行环境,理解驱动类名、JDBC URL、连接池参数等配置要点,并参考健康检查与监控报警思路排查SQL语法差异、事务管理及兼容性问题,减少自行摸索成本。
1. Nacos适配达梦数据库:从MySQL迁移到国产库的完整路径
很多团队在做信创改造时,Nacos 的配置中心和注册中心跑得好好的,唯独底层存储还挂在 MySQL 上,而甲方要求全栈国产化。这时候第一个撞上的问题就是:Nacos 默认只支持 MySQL 作为外置数据源,怎么让它认达梦?我前后在三个项目里做过这件事,从 DM8 到 Nacos 2.x 的组合踩了不少坑,今天把完整路径拆开讲。核心思路其实不复杂——Nacos 用的是 Spring 的 DataSource 抽象,理论上换驱动、改方言、导数据就能跑通,但实际操作中 SQL 语法差异、分页写法、建表脚本兼容性会让你反复翻车。这篇内容适合正在做信创适配的后端工程师、运维,以及需要把注册中心 Nacos 和配置中心一起迁到国产数据库的技术负责人。
2. 为什么Nacos换达梦不是改个JDBC URL就完事
2.1 Nacos的存储层到底依赖了哪些MySQL特性
Nacos 的外置存储模式(standalone 或 cluster 都可以配)本质上是通过 Spring JDBC 直接操作数据库,没有引入 MyBatis 或 JPA 这类 ORM 框架。这意味着所有 SQL 都是硬编码在 Java 代码和 XML 里的,换数据库就得面对这些 SQL 的兼容性。
具体来说,Nacos 对 MySQL 的依赖集中在几个地方:建表脚本mysql-schema.sql用了AUTO_INCREMENT、ENGINE=InnoDB、utf8mb4字符集这些 MySQL 专有语法;分页查询用了LIMIT offset, size的写法;时间字段用了TIMESTAMP的默认值CURRENT_TIMESTAMP;部分查询里还有INSERT ... ON DUPLICATE KEY UPDATE这种 MySQL 特有的 upsert 语法。
达梦 DM8 虽然兼容大部分标准 SQL,也提供了 MySQL 兼容模式,但默认安装下这些语法并不是全部开箱即用。所以适配的核心工作量在于:建表脚本改写、分页语法替换、upsert 语句调整,以及驱动和连接池配置。
2.2 达梦的MySQL兼容模式能省多少事
达梦 DM8 提供了一个COMPATIBLE_MODE参数,建库时可以设为 MySQL 兼容模式。设置之后,AUTO_INCREMENT、LIMIT这些语法基本能识别,但要注意几点:
第一,兼容模式是在实例初始化时指定的,已经建好的库改这个参数需要重启且不一定完全生效,所以最好在规划阶段就定好。第二,即使开了兼容模式,ON DUPLICATE KEY UPDATE仍然不保证支持,需要用达梦的MERGE INTO改写。第三,字符集方面达梦用UTF8而不是utf8mb4,建表时要对应调整。
我一般建议:如果是从零搭建,开 MySQL 兼容模式能省掉 60% 左右的脚本改写工作;如果是已有达梦实例不方便重建,那就老老实实按达梦原生语法改,工作量大概多一倍但更稳妥。
2.3 驱动选型和版本匹配的硬约束
Nacos 用的是 HikariCP 连接池,驱动层面需要引入达梦的 JDBC 驱动DmJdbcDriver18.jar(对应 JDK 8+)。这个 jar 不在 Maven 中央仓库里,需要手动安装到本地仓库或私服。
版本匹配上有个血泪经验:达梦驱动版本要和数据库服务端版本对齐,DM8 对应驱动用 8.1.x 系列。如果驱动版本低于服务端太多,连接时可能报协议不匹配;驱动太高则可能出现某些元数据接口行为变化。我一般用DmJdbcDriver18-8.1.3.140.jar这个版本,在 DM8 8.1.3 上验证过稳定。
连接 URL 的格式是jdbc:dm://host:port/DATABASE_NAME,默认端口 5236。注意达梦的大小写敏感性——默认建库时如果选了大小写敏感,表名和字段名都要严格匹配,Nacos 的 SQL 里表名是小写的,所以建库时建议选大小写不敏感,省掉一堆引号问题。
3. 手把手完成Nacos对接达梦的配置改造
3.1 达梦侧建库建用户与初始化脚本改写
先在达梦上创建一个专用数据库和用户。用 disql 或达梦管理工具执行:
-- 创建表空间(路径根据实际环境调整) CREATE TABLESPACE NACOS_DATA DATAFILE 'NACOS_DATA.DBF' SIZE 512 AUTOEXTEND ON NEXT 128 MAXSIZE 10240; -- 创建用户并指定表空间 CREATE USER NACOS IDENTIFIED BY "Nacos@2024" DEFAULT TABLESPACE NACOS_DATA; -- 授权 GRANT RESOURCE, PUBLIC TO NACOS; GRANT CREATE TABLE, CREATE VIEW TO NACOS;然后处理建表脚本。Nacos 源码的distribution/conf/mysql-schema.sql不能直接用,需要做以下替换:
| MySQL 原始写法 | 达梦改写写法 | 说明 |
|---|---|---|
AUTO_INCREMENT | IDENTITY(1,1) | 达梦自增列语法 |
ENGINE=InnoDB | 删除 | 达梦不需要存储引擎声明 |
utf8mb4 | UTF8 | 字符集名称不同 |
LIMIT 0,10 | LIMIT 10 OFFSET 0 | 达梦分页语法 |
ON DUPLICATE KEY UPDATE | MERGE INTO ... WHEN MATCHED THEN UPDATE | upsert 改写 |
TIMESTAMP DEFAULT CURRENT_TIMESTAMP | TIMESTAMP DEFAULT SYSDATE | 默认时间函数不同 |
改写后的建表脚本大概有 12 张表,核心的几张是config_info、config_info_beta、his_config_info、tenant_info。建议逐表改写后在达梦上执行验证,不要一次性全跑,出错时定位困难。
3.2 Nacos服务端的application.properties关键配置
改完数据库侧,接下来配 Nacos 服务端。在conf/application.properties里,把默认的 MySQL 配置替换为达梦:
# 关闭内置derby,启用外置数据源 spring.datasource.platform=dm db.num=1 db.url.0=jdbc:dm://192.168.1.100:5236/NACOS db.user.0=NACOS db.password.0=Nacos@2024 # 连接池参数(达梦下建议调小最大连接数) db.pool.config.maximumPoolSize=20 db.pool.config.minimumIdle=5 db.pool.config.connectionTimeout=30000 db.pool.config.validationTimeout=10000 db.pool.config.testWhileIdle=true db.pool.config.testOnBorrow=true这里有几个参数值得展开说。spring.datasource.platform设成dm是为了让 Nacos 加载对应的驱动类,但 Nacos 原生并没有dm这个 platform 的驱动映射,所以还需要在启动脚本里把达梦驱动 jar 放到 classpath 下,或者直接改nacos-server.jar的依赖。常见做法是在startup.sh的JAVA_OPT里追加-Dloader.path=plugins/dm,然后把驱动 jar 放到plugins/dm目录。
连接池参数方面,达梦的连接创建比 MySQL 稍慢,connectionTimeout建议不低于 30 秒。maximumPoolSize不要设太大,达梦对并发连接的处理能力和 MySQL 有差异,20 到 30 之间比较稳。
3.3 驱动jar的引入与启动脚本调整
达梦驱动 jar 需要手动获取,通常在达梦安装目录的drivers/jdbc下能找到。拿到DmJdbcDriver18.jar后,放到 Nacos 的plugins/dm/目录(没有就新建)。
然后修改bin/startup.sh,在JAVA_OPT变量里加上:
JAVA_OPT="${JAVA_OPT} -Dloader.path=${BASE_DIR}/plugins/dm"如果是 Windows 环境改startup.cmd,逻辑一样。注意loader.path是 Spring Boot 的PropertiesLauncher才支持的,Nacos 默认用的就是PropertiesLauncher,所以这个方式可行。
启动后看日志logs/start.out,如果出现HikariPool-1 - Start completed并且没有 SQL 异常,说明数据源通了。再用curl http://localhost:8848/nacos/v1/console/health/readiness检查健康状态。
3.4 验证配置中心与注册中心是否真正跑通
数据源通了不代表业务功能没问题。需要分两步验证:
配置中心验证:登录 Nacos 控制台,新建一个配置,然后通过 API 读取:
# 发布配置 curl -X POST "http://localhost:8848/nacos/v1/cs/configs" \ -d "dataId=test.yaml&group=DEFAULT_GROUP&content=key: value" # 读取配置 curl "http://localhost:8848/nacos/v1/cs/configs?dataId=test.yaml&group=DEFAULT_GROUP"如果发布和读取都正常,再去达梦里查config_info表,确认数据真正落库了。
注册中心验证:启动一个 Spring Cloud 服务实例注册上来,看控制台服务列表是否出现,然后停掉实例看是否自动摘除。这一步会触发INSERT、UPDATE、DELETE多种 SQL,能暴露大部分兼容性问题。
4. Nacos适配达梦过程中最容易翻车的几个点
4.1 启动报“表或视图不存在”但明明建了表
现象:Nacos 启动日志报Table 'NACOS.CONFIG_INFO' doesn't exist,但你在达梦里SELECT能查到这张表。
原因:达梦默认大小写敏感,建表时如果用了小写且没加引号,达梦会自动转成大写存储。而 Nacos 的 SQL 里写的是小写表名,查询时就找不到了。
解决:建库时选大小写不敏感模式,或者在建表时统一用大写表名并确保 Nacos 的 SQL 也匹配。最省事的办法是初始化实例时就设CASE_SENSITIVE=0。
4.2 配置列表分页查询返回空结果
现象:控制台配置列表第一页正常,翻到第二页就空了,或者总数不对。
原因:Nacos 的分页 SQL 用了 MySQL 的LIMIT offset, size语法,达梦不认这种写法,导致第二页开始的查询直接报错被吞掉或返回空。
解决:找到 Nacos 源码里所有分页查询,把LIMIT ?,?改成LIMIT ? OFFSET ?。涉及的文件主要是ExternalConfigInfoPersistServiceImpl和ExternalConfigInfoBetaPersistServiceImpl。如果不想改源码,可以在达梦的 MySQL 兼容模式下测试是否自动识别,但兼容模式对分页的支持并不完整,建议还是改源码重新编译。
4.3 配置发布时报唯一约束冲突
现象:同一个 dataId 重复发布配置时,报主键冲突或唯一索引冲突,而不是正常更新。
原因:Nacos 在 MySQL 下用INSERT ... ON DUPLICATE KEY UPDATE实现“存在即更新”,达梦不支持这个语法,语句直接变成纯 INSERT,第二次就撞唯一键了。
解决:把相关 SQL 改写成达梦的MERGE INTO语法。例如:
MERGE INTO config_info t USING (SELECT ? AS data_id, ? AS group_id, ? AS tenant_id FROM DUAL) s ON (t.data_id = s.data_id AND t.group_id = s.group_id AND t.tenant_id = s.tenant_id) WHEN MATCHED THEN UPDATE SET t.content = ?, t.gmt_modified = SYSDATE WHEN NOT MATCHED THEN INSERT (data_id, group_id, tenant_id, content, gmt_create, gmt_modified) VALUES (?, ?, ?, ?, SYSDATE, SYSDATE);4.4 集群模式下节点间数据不同步
现象:Nacos 集群两个节点,在节点 A 发布的配置,节点 B 的控制台看不到。
原因:大概率是达梦的连接数不够或者事务隔离级别差异导致。Nacos 集群间通过数据库共享数据,如果节点 B 的连接池拿不到连接,查询就会失败但被降级处理,表现为“看不到数据”。
解决:检查db.pool.config.maximumPoolSize是否够用,集群模式下每个节点建议不低于 20。另外确认达梦的事务隔离级别是READ COMMITTED,这是 Nacos 期望的默认级别。
4.5 达梦驱动加载失败导致启动直接退出
现象:启动脚本执行后进程立刻退出,日志里报ClassNotFoundException: dm.jdbc.driver.DmDriver。
原因:驱动 jar 没有正确放到 classpath,或者loader.path配置的路径不对。
解决:确认plugins/dm/目录下有DmJdbcDriver18.jar,且startup.sh里的loader.path指向的是绝对路径。可以在启动命令前加-verbose:class看类加载情况,确认驱动类是否被扫描到。
5. 进阶:让Nacos在达梦上跑得更稳的几个技巧
5.1 用达梦的AWR报告定位慢SQL
Nacos 在达梦上跑起来之后,性能问题往往出在几条高频 SQL 上。达梦提供了类似 Oracle AWR 的性能诊断工具,可以通过V$SQL_HISTORY和V$SESSION视图找到执行时间最长的 SQL。
我一般会先跑这样一条查询,找出 Nacos 相关的高频慢 SQL:
SELECT sql_text, exec_time, executions FROM V$SQL_HISTORY WHERE sql_text LIKE '%config_info%' ORDER BY exec_time DESC LIMIT 10;如果发现config_info的模糊查询慢,可以在data_id和group_id上建复合索引。达梦的索引创建语法和 MySQL 基本一致:
CREATE INDEX idx_config_dataid_group ON config_info(data_id, group_id);5.2 连接池参数的达梦调优经验值
经过几个项目的验证,下面这组连接池参数在达梦 DM8 + Nacos 2.x 的组合下比较稳:
| 参数 | 建议值 | 说明 |
|---|---|---|
| maximumPoolSize | 20 | 单节点,集群按节点数倍增 |
| minimumIdle | 5 | 保持最小空闲连接 |
| connectionTimeout | 30000 | 达梦建连较慢,不低于30秒 |
| idleTimeout | 600000 | 空闲回收时间 |
| maxLifetime | 1800000 | 连接最大存活时间,30分钟 |
| validationQuery | SELECT 1 FROM DUAL | 达梦的验证语句 |
特别提醒validationQuery,MySQL 下写SELECT 1就行,达梦要求FROM DUAL,不写会报语法错误导致连接池健康检查失败。
5.3 从MySQL迁移已有数据到达梦的实操步骤
如果 Nacos 已经在 MySQL 上跑了一段时间,迁移时不能只建空表,还得把存量配置数据搬过去。我一般用这个流程:
第一步,在 MySQL 上导出数据为 CSV 或 SQL 插入语句。第二步,用达梦的数据迁移工具 DTS 或者手工改写 INSERT 语句导入。注意时间字段格式,MySQL 的datetime导出来是2024-01-15 10:30:00,达梦能直接识别。第三步,导入后核对行数:
-- MySQL侧 SELECT COUNT(*) FROM config_info; -- 达梦侧 SELECT COUNT(*) FROM config_info;两边数字一致后再切换 Nacos 的数据源配置。切换前建议停写几分钟,避免迁移过程中有新配置写入导致遗漏。
5.4 一个容易被忽略的字符集问题
达梦建库时如果字符集选了GBK,Nacos 里存储中文配置内容会出现乱码。这个问题在测试环境不一定暴露,因为测试配置往往是英文的。上线后用户写中文配置就翻车了。
确认字符集的方法:
SELECT UNICODE_TYPE FROM V$INSTANCE;返回UTF8才正常。如果是GBK,要么重建库,要么在 Nacos 连接 URL 上加字符集参数试试,但根治还是重建。这个坑我在一个项目上线当天遇到过,后悔药没得吃,只能连夜导数据重建。
5.5 升级Nacos版本时怎么保住达梦适配
Nacos 版本升级时,官方不会维护达梦的适配代码,所以每次升级都要重新打补丁。我的习惯是把达梦适配的改动集中管理:建表脚本单独放一个dm-schema.sql,分页和 upsert 的源码改动用 git patch 文件记录,升级时先合官方代码再 apply patch。
具体操作上,维护一个dm-adaptation.patch,每次升级后执行:
git apply dm-adaptation.patch如果官方改了相关文件导致 patch 冲突,就手动合并。这样比每次重新改一遍源码靠谱得多。另外建议把达梦驱动 jar 也纳入版本管理,避免换台机器就找不到驱动。
这套方案我已经在三个信创项目里落地过,最长的稳定跑了两年多。核心经验就是:建库时把大小写和字符集定对,分页和 upsert 的 SQL 改到位,驱动和连接池参数调稳,剩下的就是常规运维了。希望帮到你。
本文还有配套的精品资源,点击获取