
记一次 Druid 连接 MySQL 报 Communications link failure 的排查过程问题现象Druid 连接池启动时报错com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:361) ... Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are in连接地址是jdbc:mysql://127.0.0.1:3306/k_kMySQL 就在本机。排查过程1. 先排除基础问题确认 MySQL 服务在运行、端口 3306 可通排除服务没启动、防火墙拦截等常见原因。2. 定位到 SSL 握手阶段堆栈里最关键的一行是at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:361)说明 TCP 连接已经建立问题出在SSL 握手阶段而不是网络不通。3. 检查 MySQL 的 TLS 配置SHOWVARIABLESLIKEtls_version;结果TLSv1,TLSv1.1,TLSv1.2MySQL 支持 TLSv1.2但同时也启用了已被淘汰的 TLSv1 和 TLSv1.1。4. 获取 CA 证书MySQL 启用 SSL 后数据目录下会生成一组证书文件。先找到数据目录SHOWVARIABLESLIKEdatadir;在数据目录里找到ca.pem这就是服务端的 CA 证书。5. 将 CA 证书导入 Java 信任库使用 JDK 自带的keytool/www/server/java/jdk1.8.0_371/bin/keytool-importcert\-aliasMySQLCACert\-file/www/server/data/ca.pem\-keystoretruststore.jks\-storepass你的密码生成的truststore.jks位于执行命令时的当前目录。6. 在 JDBC URL 中配置信任库jdbc:mysql://127.0.0.1:3306/k_k?sslModeVERIFY_CAtrustCertificateKeyStoreUrlfile:/路径/truststore.jkstrustCertificateKeyStorePassword你的密码重新启动后仍然报同样的错。真正的原因这是MySQL Connector/J 8.0.18 及更早版本的一个已知设计问题Connector/J 8.0.16 出于兼容旧版 MySQLyaSSL 编译的考虑默认不启用 TLSv1.2只尝试用 TLSv1/TLSv1.1 协商。JDK 8u371 默认禁用了 TLSv1 和 TLSv1.1这两个不安全的旧协议。双方在“能用哪个协议”上谈不拢SSL 握手直接失败。解决方案在 JDBC URL 中显式指定 TLS 协议版本jdbc:mysql://127.0.0.1:3306/k_k?sslModeVERIFY_CAtrustCertificateKeyStoreUrlfile:/路径/truststore.jkstrustCertificateKeyStorePassword你的密码enabledTLSProtocolsTLSv1.2关键是enabledTLSProtocolsTLSv1.2它强制驱动使用 TLSv1.2打破协议僵局。加上后连接正常。几个容易踩的坑ssl_cipher查询为空是正常的MySQL 8.0 的密码套件由底层 OpenSSL 管理不再通过该变量显式列出。ssl_ca只返回ca.pem而非完整路径也是正常的该变量存储的是配置文件里填写的值要拿绝对路径得查datadir。keytool命令找不到是因为它不在系统 PATH 里需要用 JDKbin目录下的绝对路径执行。后续可以改进的地方升级驱动Connector/J 8.0.19 及以上版本已修复默认不启用 TLSv1.2 的问题升级后可以去掉enabledTLSProtocols参数。清理 MySQL 旧协议在my.cnf的[mysqld]段加上tls_versionTLSv1.2,TLSv1.3重启 MySQL让服务端也彻底禁用旧协议安全性更好。最终可用配置jdbc:mysql://127.0.0.1:3306/k_k?sslModeVERIFY_CAtrustCertificateKeyStoreUrlfile:/路径/truststore.jkstrustCertificateKeyStorePassword你的密码enabledTLSProtocolsTLSv1.2版本信息MySQL Connector/J 8.0.16Druid 1.1.18JDK 1.8.0_371