由于数据库使用的是MySQL5.7的版本,我的新机器装的JDK8,跑项目的时候启动失败并发生了javax.net.ssl.SSLHandshakeException,一下子给我弄蒙了。经过一系列的排查(排查网络问题、环境问题、数据库问题等等,其实就是走了很多弯路,这就体现了好好看日志的重要性),定位到是SSL协议的问题。
发生该问题的原因是因为协议没对上,其实就是日志里面说的SSL握手失败,所以导致程序和数据库的连接失败,导致数据源初始化失败等一系列问题。。。
那知道了问题的原因,是什么导致了该问题的产生呢?为啥我原来的版本没有遇到过这个问题呢?经过笔者调研:jdk8从小版本JDK8u261开始支持TLS1.3,默认TLS1.2之前的协议在security里面是禁用的,所以从JDK8u261开始只有TLS1.2和1.3是默认启用的;MySQL在8.0.26以及之后的版本,TLS1.0和TLS1.1已经被废弃,但是可以作为握手的协议,会在MySQL的日志记录器中提示这些协议会在未来被删除,对于8.0.18以及之前的版本,包括5.6,5.7来说,为了兼容性的原因,不会启用1.2以及更高版本的TLS协议,所以MySQL 5.7这里默认是TLS1.0,TLS1.1被使用。所以,JDK8支持TLS1.2和1.3,MySQL支持TLS1.0和1.1,协议完全对不上,所以导致了上述的握手失败的问题。
既然我们剖析完了问题以及产生原因,我们怎样解决该问题呢?有三种解决方案:
方案一:
在项目的MySQL连接配置的地方加上useSSL=false的参数。
方案二:
把本地的JDK的协议栈全部打开。打开的方法为编辑$JAVA_HOME/jre/lib/security/java.security文件,找到jdk.tls.disabledAlgorithms的配置项,将其全部注释掉。
方案三:
在项目的MySQL连接配置上加上enabledTLSProtocols=TLSv1.2的参数来指定连接的协议栈。
文章评论