使用 JDBC 和 MySQL 解決「通訊鏈路故障」問題
P粉633309801
2023-08-28 10:53:42
<p>我正在尝试连接到本地 MySQL 服务器,但不断收到错误消息。</p>
<p>这是代码。</p>
<pre class="brush:php;toolbar:false;">public class Connect {
public static void main(String[] args) {
Connection conn = null;
try {
String userName = "myUsername";
String password = "myPassword";
String url = "jdbc:mysql://localhost:3306/myDatabaseName";
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, userName, password);
System.out.println("Database connection established");
} catch (Exception e) {
System.err.println("Cannot connect to database server");
System.err.println(e.getMessage());
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
System.out.println("Database Connection Terminated");
} catch (Exception e) {}
}
}
}
}</pre>
<p>以及错误:</p>
<pre class="brush:php;toolbar:false;">Cannot connect to database server
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.
com.mysql.jdbc.exceptions.jdbc4.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 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2333)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2370)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2154)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
at Connect.main(Connect.java:16)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:218)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:257)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:294)
... 15 more</pre>
<p>我已经设置了类路径,确保 my.cnf 已注释掉跳过网络选项。 </p>
<p>java版本是1.2.0_26(64位)
mysql 5.5.14
mysql连接器5.1.17</p>
<p>我确保用户有权访问我的数据库。</p>
我的兩個程式中也遇到了同樣的問題。我的錯誤是這樣的:
我花了幾天時間才解決這個問題。我測試了不同網站上提到的許多方法,但沒有一個有效。最後我更改了程式碼並找出了問題所在。我將嘗試向您介紹不同的方法,並在此處進行總結。
當我在互聯網上尋找此錯誤的解決方案時,我發現有許多解決方案至少對一個人有效,但其他人說這對他們不起作用!
strong> 為什麼有很多方法可以解決這個錯誤? 看起來通常當連接到伺服器時出現問題時,就會發生此錯誤。也許問題是因為錯誤的查詢字串或與資料庫的連接太多。所以我建議你一一嘗試所有的解決方案,不要放棄!
以下是我在網路上找到的解決方案,對於每個解決方案,至少有一個人的問題已透過該解決方案解決。
提示:需要更改MySQL設定的解決方案可以參考以下檔案:
Linux:
/etc/mysql/my.cnf
或/etc/my.cnf
(取決於Linux 發行版和使用的MySQL 軟體包) p>Windows:
C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini
(注意它是 ProgramData,而不是 Program Files)以下是解決方案:
更改
bind-address
屬性:取消註解
bind-address
屬性或將其變更為以下 IP 之一:或
註解掉「skip-networking」
#如果 MySQL 設定檔中有
skip-networking
行,請在該行的開頭加上# 符號將其註解。
更改「wait_timeout」和「interactive_timeout」
#將這些行新增到 MySQL 設定檔:
確保 Java 不會將「localhost」翻譯為 [:::1] 而不是 [127.0.0.1]
由於MySQL 可以辨識
127.0.0.1
(IPv4
),但無法辨識:::1
(IPv6
#)可以透過使用以下兩種方法之一來避免這種情況:
在連線字串中使用
127.0.0.1
而不是localhost
以避免localhost
被轉換為::: 1
使用選項
-Djava.net.preferIPv4Stack=true
執行java以強制java使用IPv4
而不是IPv6
。在 Linux 上,這也可以透過運行(或將其放入/etc/profile
中來實現:檢查作業系統代理設定、防火牆和防毒程式
確保防火牆或防毒軟體沒有封鎖 MySQL 服務。
在 Linux 上暫時停止 iptables。如果 iptables 設定錯誤,它們可能允許 tcp 封包發送到 mysql 端口,但阻止 tcp 封包返回相同連接。
停止 Windows 上的防毒軟體。
更改連接字串
檢查您的查詢字串。你的連接字串應該是這樣的:
確保字串中沒有空格。所有連接字串都應該連續,沒有任何空格字元。
嘗試將「localhost」替換為環回位址 127.0.0.1。 也嘗試將連接埠號碼新增至連接字串中,例如:
通常 MySQL 的預設連接埠是 3306。
不要忘記將使用者名稱和密碼更改為您的 MySQL 伺服器的使用者名稱和密碼。
#「max_allowed_packet」是MySQL 設定檔中的一個變量,指示最大資料包大小,而不是最大資料包數量。所以這對解決這個錯誤沒有幫助。
將 TOMCAT6_SECURITY=yes 改為 TOMCAT6_SECURITY=no
使用validationQuery="select now()"確保每個查詢都有回應
#將此程式碼新增至您的連接字串:
雖然這些解決方案都不適合我,但我建議您嘗試一下。因為有些人按照這些步驟解決了他們的問題。
但是是什麼解決了我的問題呢?
我的問題是我在資料庫中有很多 SELECT。每次我創建連接然後關閉它。雖然我每次都關閉連接,但是系統面臨很多連接並給了我這個錯誤。 我所做的是將連接變數定義為整個類別的公共(或私有)變量,並在建構函數中初始化它。 然後每次我使用該連接時。它解決了我的問題,也大大提高了我的速度。
#結論# 沒有簡單且獨特的方法來解決這個問題。建議您結合自身情況考慮,選擇以上解決方案。如果您在程式開始時出現此錯誤並且根本無法連接到資料庫,則您的連接字串可能有問題。但是,如果您在與資料庫進行多次成功交互後出現此錯誤,則問題可能出在連接數上,您可能會考慮更改“wait_timeout”和其他 MySQL 設置,或者重寫代碼以減少連接數。