背景
新项目使用springboot 3.x开发对接msql数据,使用springboot 2.x对接msyql的配置,突然报错了:com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure. 明明完全一模一样的配置,本文记录处理分析过程。
问题描述
项目配置
- springboot版本: 2.3.2.RELEASE
- java版本: java11
- msyql驱动版本: mysql-connector-java:8.0.18
- 数据配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.4.187:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
username: root
password: 123456
报错信息
报错表象: 连接3次失败,放弃
报错本质原因:
解决方案
从报错日志中关键字分析,“javax.net.ssl"和"HandshakeContext” 这个一般和网络安全协议通信(安全套接字层(SSL) 是一种安全协议)有关。以下有两种解法,都可以解决这个报错。但是解决方式有所不同,解决问题,不仅要知其然也要知其所以然
解决方案1 (不推荐)
第一种方式,也是网上很多介绍处理方法,既然是ssl有问题,那直接关闭不就好了.
解决方式: jdbc连接补充&useSSL=false 关闭ssl配置
补充配置后如下
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.4.187:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
username: root
password: 123456
问题解决!是不是打算提交代码了。
但是!这么有风险的,以下是生产环境禁用SSL可能带来的一些潜在风险:
-
数据安全性风险: 禁用SSL可能会导致数据在传输过程中以明文形式在网络上传输,这增加了数据被窃听的风险。敏感信息如用户凭据、个人身份信息等可能会受到威胁。
-
中间人攻击: 没有SSL加密,数据传输过程中可能容易受到中间人攻击。攻击者可以在数据传输过程中窃取、篡改或伪造数据,对系统造成损害。
-
合规要求: 某些行业或法规要求对数据传输过程进行加密保护,禁用SSL可能违反这些合规要求,导致可能的法律责任和罚款。
-
身份验证风险: SSL连接不仅提供加密,还提供了服务器身份验证的机制,确保客户端连接到正确的服务器。禁用SSL可能使得客户端难以验证服务器的身份,存在连接到恶意服务器的风险。
综上: useSSL=false 能用,但是不建议生产环境用。
解决方案2 (推荐)
useSSL=false 方案虽然可以解决问题,但是只是治标。那怎么整,还是看日志提示。
protocol is disabled or cipher suites are inappropriate 字面翻译: 协议被禁用或密码套件不合适
-
协议版本不兼容: 客户端和服务器之间协商的 SSL/TLS 协议版本不兼容。可能是因为客户端或服务器使用的是较旧的 SSL/TLS 版本,而目标服务器或客户端要求使用较新的协议版本。
-
密码套件不匹配: 客户端和服务器之间协商的密码套件不兼容。可能是因为客户端或服务器支持的加密套件与目标服务器或客户端支持的不同。
关键在于or后面部分, 连接同一个mysql数据库,mysql驱动版本虽然也相同,但是底层的ssl一般是jdk底层提供的。在分析两个项目的差异部分: 因为升级了springboot版本,jdk版本也连带变化。变化如下:
- springboot: 2.3.2.RELEASE (笔者使用java 11)
- springboot: 3.2.2 (最低要求 java17,笔者使用java 21 最新的长期支持版本)
项目使用的:mysql-connector-java:8.0.18 java11没问题,但是java 21版本发布较迟(2023年9月20日)
jdk变化太大客户端适配有问题。java21 是目前最新的,那么驱动也用最新。
maven依赖更新8.0.18->8.0.33
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<!-- <version>8.0.18</version>-->
</dependency>
报错消失,jdbc的url也不需要做任何修改。
- url: jdbc:mysql://192.168.4.187:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
附录
mysql连接参数配置
jdbc:mysql://192.168.4.187:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
这是一个MySQL数据库的JDBC连接字符串,以下是每个参数的作用:
- useUnicode=true:设置为true表示使用Unicode字符集。这个参数确保数据库连接正确地处理Unicode字符。
- characterEncoding=UTF-8:指定字符编码为UTF-8。这个参数确保在与数据库通信时正确地编码和解码字符。
- autoReconnect=true:设置为true表示开启自动重新连接功能。
当连接中断时,JDBC驱动会尝试重新连接数据库
驱动类区别
- com.mysql.cj.jdbc.Driver支持MySQL 5.7及更高版本的新连接协议。
- com.mysql.jdbc.Driver通常与较旧的MySQL版本一起使用,可能不支持最新的连接协议。