問題描述
App Service使用jdbc連接MySQL服務(wù),出現(xiàn)大量的** Communications link failure:**
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
問題分析
最開始出現(xiàn)連接不上的原因,懷疑是MySQL服務(wù)的IP地址白名單沒有配置正確的App Service 出站IP。但是根據(jù)錯(cuò)誤提示,發(fā)現(xiàn)明顯不對(duì),因?yàn)槿绻荌P地址不允許訪問,它的錯(cuò)誤消息應(yīng)該是:
Client with IP address '183.2xx.xx.xx' is not allowed to connect to this MySQL server.
所以不應(yīng)該是MySQL服務(wù)器對(duì)IP白名單設(shè)置的問題。
為了深入找出問題,單獨(dú)用Java Spring Boot來寫一個(gè)簡(jiǎn)單的數(shù)據(jù)庫連接代碼,根據(jù)MySQL官方的代碼:https://docs.azure.cn/zh-cn/mysql/connect-java
POM.XML內(nèi)容為:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
</dependencies>
</project>
注:這里使用的 mysql-connector-java 依賴版本為 8.0.20
Java Main函數(shù)代碼:
public static void main(String[] args) {
String url = "jdbc:mysql://xxxxxx.mysql.database.chinacloudapi.cn:3306/xxxxxx?useSSL=true&requireSSL=false&characterEncoding=utf8&serverTimezone=UTC";
String username = "xxxxxx@xxxxxx";
String password = "xxxxxxxxxxxx";
try {
Connection connection = DriverManager.getConnection(url, username, password);
System.out.println(connection.getMetaData().getURL());
connection.close();
System.out.println("connected!");
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
return; // return because nothing can be done w/out a connection
}
}
同樣的數(shù)據(jù)庫連接字符串,運(yùn)行結(jié)果正常。根據(jù)驗(yàn)證結(jié)果對(duì)比,出現(xiàn) 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, 的JDBC版本為 8.0.15, 所以瞬間定位問題原因:客戶端jdbc的驅(qū)動(dòng)問題。
根據(jù)這一判斷,再次檢查了MySQL的版本為8.0并且為單實(shí)例(Single Server)。而微軟的官方文檔中提示了 use 8.0.17+ with MySQL 8.0 (https://docs.microsoft.com/en-us/azure/mysql/concepts-compatibility#mysql-drivers)
隨后,對(duì)mysql-connector jdbc的版本 8.0.17, 8.0.18, 8.0.19這三個(gè)版本進(jìn)行驗(yàn)證,看是否不會(huì)出現(xiàn) Communications link failure 異常:
8.0.17 Error
8.0.18 Error
8.0.19 Successful
經(jīng)過以上驗(yàn)證,得出微軟官方文檔中的 8.0.17+有問題,需要在8.0.19+的驅(qū)動(dòng)版本后才能成功。(一個(gè)調(diào)查了三天的大坑)
參考資料
將 Java 和 JDBC 與 Azure Database for MySQL 配合使用 : https://docs.azure.cn/zh-cn/mysql/connect-java
當(dāng)在復(fù)雜的環(huán)境中面臨問題,格物之道需:濁而靜之徐清,安以動(dòng)之徐生。 云中,恰是如此!
標(biāo)簽: App Service, Azure Developer, JDBC連接MYSQL, Communications link failure