结论先说:如果 Java 服务使用 jdbc:TAOS://,运行时会加载本机的 libtaos.so。服务端是 3.2.0.0,本机却装了 3.4.2.8,即使网络和端口都正常,也可能在 JNI 握手阶段失败。应先让本机客户端库与服务端版本对齐。

现象:应用启动时 TDengine 数据源失败

一个 Java 服务在启动阶段初始化 TDengine 数据源时,出现:

1
2
HikariPool$PoolInitializationException:
Failed to initialize pool: JNI ERROR (0x2354): Unable to establish connection

异常链很长:

1
2
3
4
5
6
dataSourcePoolMetadataMeterBinder
  -> prometheusMeterRegistry
  -> dataSource
  -> HikariPool
  -> TSDBJNIConnector
  -> JNI ERROR (0x2354)

外层异常可能经过数据源监控与连接池初始化,看上去像是框架配置问题。最有价值的线索是最底层的 TSDBJNIConnector:它意味着失败发生在 TDengine 的 native/JNI 层。

端口能通,为什么仍然连不上?

本机到远程 TDengine 的 6030 端口能够建立 TCP 连接。这个结果只证明了网络层没有完全断开,并不能证明以下事情都正常:

  • TDengine 原生协议握手;
  • 本机动态库加载;
  • 客户端与服务端版本协商;
  • 账号认证与集群节点 FQDN 解析。

换句话说:

TCP 端口可达 ≠ jdbc:TAOS:// 一定可用。

TDengine 官方 Java 文档明确说明,native JDBC 依赖操作系统上的客户端动态库:Linux 是 libtaos.so,Windows 是 taos.dll,macOS 是 libtaos.dylib。因此,Maven 里 JDBC 驱动版本正确,不代表实际加载的 native 库也正确。

Native、REST 与 WebSocket:到底差在哪?

TDengine 现在有三条常见的连接路径。它们的差异不在 SQL 写法,而在应用连接到哪一个组件、是否依赖本机动态库,以及可用的能力范围。

方式 连接路径与默认端口 本机依赖 能力与限制 适合什么场景
Native 应用 → taosc / libtaos.sotaosd:6030 必须安装 taosc,Java 需要 libtaos.so 可使用连接器的完整 native 能力;但 Java、Go、C#、ODBC 的 Native 连接将在 2027-01-01 下线 存量应用短期维持,且已验证客户端库与服务端版本一致
REST 应用 → HTTP → taosAdapter:6041taosd 不需要客户端驱动 仅执行 SQL;不支持参数绑定和数据订阅 临时脚本、用 HTTP 工具排障,或只需要简单 SQL 调用的集成
WebSocket 应用 → WebSocket → taosAdapter:6041taosd Java 不需要客户端驱动 支持参数绑定、订阅等连接器能力;支持多端点、自动重连等功能 新建服务与计划改造的存量服务,官方推荐的方向

Native 的优势是直连 taosd,不额外经过 taosAdapter;代价是应用运行环境与服务端绑定得更紧。本次故障就是这种耦合的直接后果:JAR 中的 JDBC 驱动最终加载了系统里的 libtaos.so,而它的版本已经偏离服务端。

REST 的优点是简单:应用不需要安装 libtaos.so,用普通 HTTP 客户端就能调用 taosAdapter。但它的能力边界也很明确,官方文档说明 REST API 仅提供执行 SQL 的能力,不支持参数绑定和数据订阅。因此,REST 更适合轻量集成或排障,不适合承担需要参数绑定或订阅的服务主链路。

WebSocket 也通过 taosAdapter:6041 通信,但它是官方现在推荐的连接器通道。对 Java 来说,迁移的核心变化是把 jdbc:TAOS:// 改成 jdbc:TAOS-WS://,驱动类改为 com.taosdata.jdbc.ws.WebSocketDriver。官方说明,从 taos-jdbcdriver 3.4.0 起推荐用 WebSocket 替代 REST;它具有更低延迟、自动重连和更丰富的功能。

迁移前提:不要把“官方推荐 WebSocket”理解成可以不做测试地直接改 URL。官方的 WebSocket 兼容性保证覆盖 TDengine 3.3.6.0 及以上服务端,Java 连接器需 3.6.0 及以上;服务端仍为 3.2.0.0 时,不在该保证范围内。迁移前应验证 SQL、认证、订阅和故障恢复。

根因:客户端库版本与服务端不匹配

这次环境的版本组合是:

组件 版本
TDengine 服务端 3.2.0.0
Java taos-jdbcdriver 3.2.5
出问题时本机 taos / libtaos.so 3.4.2.8

官方 FAQ 说明,客户端与服务端的版本号前三位需要一致才能兼容;发布历史也要求客户端驱动 libtaos.so 与服务端同步升级。对 Native JDBC 来说,这条规则尤其重要,因为驱动最终会通过 JNI 调用本机库。

因此,排查 JNI ERROR 时,优先确认下面四项,而不是先猜密码或网络:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1. 本机客户端版本
taos --version

# 2. 本机实际安装的 native 库
ls -l /usr/local/taos/driver/libtaos.so*

# 3. Java 服务中的驱动版本
# 在 pom.xml 或依赖树中查找 taos-jdbcdriver

# 4. 远程服务端版本
# 在服务器上执行 taos --version,或向运维同学确认

在本例中,将本机客户端库改为 3.2.0.0 后,应用恢复连接。这也排除了“单纯端口不通”或“密码一定错误”的判断。

重装系统后:如何恢复 3.2.0.0 历史版本

官方软件源通常只保留较新的包,不能直接通过软件源安装指定的旧版本。此次使用官方保留的历史安装包:

1
2
3
4
5
6
curl -fL -o /tmp/TDengine-server-3.2.0.0-Linux-x64.tar.gz \
  https://www.taosdata.com/assets-download/3.0/TDengine-server-3.2.0.0-Linux-x64.tar.gz

tar -xzf /tmp/TDengine-server-3.2.0.0-Linux-x64.tar.gz -C /tmp
cd /tmp/TDengine-server-3.2.0.0
sudo ./install.sh

安装脚本会交互询问配置。本机只需作为远程 TDengine 的 Native JDBC 客户端时,可以采用以下默认选择:

提示 选择
节点公开地址或 FQDN 直接回车,使用本机主机名
是否加入已有集群 直接回车,不加入
支持邮箱 直接回车,跳过

安装完成后先验证版本,不要只看脚本最后的成功提示:

1
2
taos --version
ls -l /usr/local/taos/driver/libtaos.so*

本次期望并实际得到的关键结果是:

1
2
version: 3.2.0.0
/usr/local/taos/driver/libtaos.so.3.2.0.0

一个额外的坑:安装包默认开启了本地服务

历史服务端安装包不仅安装客户端库,还会注册并启用 taosdtaosadaptertaoskeeper 三个 systemd 服务。

如果本机只是开发机,应用连接的是远程 TDengine 服务端,这些本地服务没有必要常驻。可以关闭并取消开机自启:

1
sudo systemctl disable --now taosd taosadapter taoskeeper

再检查状态:

1
2
sudo systemctl is-enabled taosd taosadapter taoskeeper
sudo systemctl is-active taosd taosadapter taoskeeper

预期输出是 disabledinactive。注意,systemctl is-active 发现服务未运行时会以非零状态退出,这是正常的状态反馈,并不代表命令执行失败。

关闭服务不会卸载 taoslibtaos.so,也不会影响 Java 程序连接远程 TDengine。

兼容性速查表

场景 官方结论 实践建议
原生客户端与服务端 客户端与服务端版本前三位需一致;libtaos.so 应随服务端同步升级 服务端 3.2.0.0 时,使用本机 3.2.0.0 客户端库
Java Native JDBC jdbc:TAOS:// 依赖本机 libtaos.so 检查 Java 依赖和系统动态库两个层级
REST API 经由 taosAdapter 提供 HTTP 接口;只支持执行 SQL,不支持参数绑定和订阅 用于轻量 SQL 调用或排障,不作为需要订阅或参数绑定的主连接方式
仅作为应用客户端 官方说明只需配置客户端连接信息,无需在本机部署服务节点 优先安装客户端包;若使用历史服务端包,关闭本机服务
社区版与企业版(3.4.0.0 起) 两者不完全兼容,错误组合会出现 Edition not compatible 升级时同时对齐版本号和发行版类型
WebSocket 连接 Java 不依赖本机客户端动态库;3.3.6.0+ 服务端配合 Java 3.6.0+ 可获得官方兼容性保证 长期优先评估 jdbc:TAOS-WS://;服务端为 3.2.0.0 时先完成联调

下次排查清单

遇到 TSDBJNIConnectorJNI ERROR 或 TDengine 数据源初始化失败时,按这个顺序走:

  1. 确认日志中到底是哪一个数据源失败;
  2. 查看异常链最底层,判断是否进入 JNI/native 层;
  3. 检查本机 taos --versionlibtaos.so
  4. 确认远程服务端版本;
  5. 检查 6030 可达性、FQDN/DNS 和账号;
  6. 最后再调整 Spring 的数据源配置。

这样可以避免被外层的 Spring 异常带偏,也不会把“端口能通”误判成“TDengine 一定能连”。

AI 协助创作说明

本文由作者基于实际排查与环境恢复过程撰写;AI 协助梳理文章结构、提炼排查步骤并核对官方资料。文中的版本、命令和兼容性结论以文末官方资料及实际验证为准。

参考资料