java連接mysql數(shù)據(jù)庫useSSL問題及解決
背景
Java spring程序,Java版本 java version "1.8.0_301"。
JDBC驅(qū)動版本5.1.40 (mysql-connector-java-5.1.40.jar) ,連接 proxysql 代理A 沒有問題,直連接代理之后的mysql數(shù)據(jù)庫實例B 報錯
- proxysql 版本
mysql> show variables like '%version%'; +----------------------+---------------------+ | Variable_name | Value | +----------------------+---------------------+ | admin-version | 2.0.13-107-g91737e0 | | mysql-server_version | 5.5.30 | +----------------------+---------------------+ 2 rows in set (0.00 sec)
- mysql數(shù)據(jù)庫實例B 版本
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1988 Server version: 5.7.27-30-log
問題根源
目前是去掉proxysql層,采用服務(wù)直接連接mysql數(shù)據(jù)庫實例,在賬號、密碼、連接正確的情況下,切換報錯
?com.alibaba.druid.pool.DruidDataSource : create connection SQLException, url: jdbc:mysql://xxxxx:3306/uuuu?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true, errorCode 0, state 08001
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.... ...
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:101)
at sun.security.ssl.TransportContext.kickstart(TransportContext.java:238)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:394)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:149)
... 25 common frames omitted
1、從錯誤日志中得知和SSL有關(guān)系
2、分別去確認 proxysql 和 mysql 發(fā)現(xiàn), proxysql 沒有開啟ssl,而mysql實例是開啟了 ssl的
- proxysql 檢查 ssl 是否開啟
mysql> show variables like '%ssl%' ; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | mysql-have_ssl | false | | mysql-session_idle_show_processlist | true | | mysql-show_processlist_extended | 0 | | mysql-ssl_p2s_ca | | | mysql-ssl_p2s_cert | | | mysql-ssl_p2s_key | | | mysql-ssl_p2s_cipher | | +-------------------------------------+-------+
- mysql數(shù)據(jù)庫 檢查 ssl 是否開啟
mysql> show variables like '%ssl%' ; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | have_openssl | YES | | have_ssl | YES | | ssl_ca | ca.pem | | ssl_capath | | | ssl_cert | server-cert.pem | | ssl_cipher | | | ssl_crl | | | ssl_crlpath | | | ssl_key | server-key.pem | +---------------+-----------------+
3、但是從程序的配置文件中得知是沒有配置 ssl相關(guān)的
datasource.analysisMaster.driverClassName=com.mysql.jdbc.Driver datasource.analysisMaster.url=jdbc:mysql://xxxxx:3306/uuuu?&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true datasource.analysisMaster.username=userxxxx datasource.analysisMaster.password=passyyyy datasource.analysisMaster.maxSize=10 datasource.analysisMaster.minIdle=5
擴展
spring 整合 druid作為連接池
1)pom.xml 文件中添加相關(guān)依賴
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
2)配置數(shù)據(jù)庫連接,如上面的datasource 配置,一般存放項目config目錄或者 Apollo配置中心等
3)spring 加載druid的配置,加載方式看具體配置的存放方式
4、所以懷疑是 useSSL jdbc 參數(shù)在不同實例下默認值不同導致的
5、既然這里 DataSource中沒有配置SSL相關(guān),那么就看 JDBC URL 中對于 useSSL的默認值設(shè)置,找到官方文檔說明

參考 https://dev.mysql.com/doc/connectors/en/connector-j-connp-props-security.html#cj-conn-prop_useSSL
從這里可以得知
1、目前mysql驅(qū)動 5.1.40,是低于 8.0.12的
2、proxysql的版本是 5.5.30 是不包含在 MySQL 5.5.45+、5.6.26+ or 5.7.6+的,所以 useSSL 默認是false
3、MySQL數(shù)據(jù)庫實例版本是 5.7.27,是滿足條件 mysql 5.7.6+ 的,所以useSSL 默認是True
結(jié)論符合之前的猜測。
修改datasource的URL地址,添加 &useSSL=false ,重啟服務(wù),問題解決
知識點
1、Java連接mysql驅(qū)動是 mysql-connector-java-xx.jar ,驅(qū)動升級的時候,升級該Jar包即可。而且高版本是兼容低版本的,所以建議使用高版本驅(qū)動
2、數(shù)據(jù)庫一般是部署在內(nèi)網(wǎng)環(huán)境的,一般情況不會開啟數(shù)據(jù)庫的SSL。而且高版本(>=8.0.13)的驅(qū)動默認useSSL=true ;所以建議JDBC URL配置中明確配置useSSL=false
3、發(fā)現(xiàn)問題和 ssl 有關(guān)系,那么添加 useSSL=false 會立刻解決問題。但是在精力允許的情況下,還是建議要知其然知其所以然才好~
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- MySQL存儲過程全面解析以及和Java的類比教程
- MySQL時間類型與Java日期時間類對應(yīng)關(guān)系示例詳解
- 如何通過mysql-connector-java實現(xiàn)Java與MySQL的連接詳解
- mysql-connector-java和mysql-connector-j的區(qū)別及說明
- mysql-connector-java驅(qū)動jar包下載方式
- Java通過驅(qū)動包(jar包)連接MySQL數(shù)據(jù)庫的步驟總結(jié)及驗證方式
- Java日期格式化之IllegalArgumentException與MySQL數(shù)據(jù)截斷問題解決
- JAVA+MySQL實現(xiàn)分庫分表的項目實踐
相關(guān)文章
mysql中DATE_FORMAT()函數(shù)的具體使用
在MySQL中,DATE_FORMAT()函數(shù)用于將日期/時間類型的值按照指定的格式進行格式化輸出,具有一定的參考價值,感興趣的可以了解一下2024-05-05
MySQL性能優(yōu)化之全文檢索查詢優(yōu)化實踐
當內(nèi)容量達到數(shù)十萬甚至數(shù)百萬條記錄時,簡單的全文檢索實現(xiàn)可能導致響應(yīng)時間延長等問題,下面小編就來和大家講講MySQL如何進行全文檢索查詢優(yōu)化吧2025-07-07
Mysql數(shù)據(jù)表分區(qū)技術(shù)PARTITION淺析
這篇文章主要介紹了Mysql數(shù)據(jù)表分區(qū)技術(shù)PARTITION淺析,分別介紹了 Mysql 中的分區(qū)技術(shù) RANGE、LIST、 HASH,需要的朋友可以參考下2014-06-06
MySQL中CONCAT()函數(shù)出現(xiàn)值為空的問題及解決辦法
項目中查詢用到了concat()拼接函數(shù),本文主要介紹了MySQL中CONCAT()函數(shù)出現(xiàn)值為空的問題及解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-07-07
Mysql數(shù)據(jù)庫百萬級數(shù)據(jù)測試索引效果
這篇文章主要為大家介紹了Mysql數(shù)據(jù)庫百萬數(shù)據(jù)測試索引效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06

