線上故障:應用伺服器(Tomcat + JDBC)無法連線 MySQL,報 Communications link failure;但同機器 Terminal 下 mysql -uroot -p 正常。經排查,MySQL 進程存在、Unix Socket 正常,**但 3306 TCP 端口未監聽**。根因:my.cnf 中 skip-networking 未註釋,導致 MySQL 僅支援本地 Socket 連線,關閉 TCP/IP 監聽。
CommunicationsException: Communications link failuremysql -uroot -p 可操作netstat -talnp **無 3306 端口**ps aux | grep mysql 進程存在lsof -i :3306 無輸出
ps aux | grep mysql
# 顯示 mysqld_safe 與 mysqld 進程正常運行
netstat -talnp
# 正常應有:tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1234/mysqld
# 故障機:無此行
lsof -i :3306
# 正常顯示 mysqld 持有 TCP *:mysql (LISTEN)
# 故障機:無輸出
檢視 /etc/my.cnf(或 /etc/mysql/my.cnf):
# 發現以下行未註釋:
skip-networking
官方註釋說明:
Don't listen on a TCP/IP port at all. This can be a security enhancement, if all processes that need to connect to mysqld run on the same host. All interaction with mysqld must be made via Unix sockets or named pipes.
# 1. 編輯配置檔,註釋 skip-networking
sed -i 's/^skip-networking/#skip-networking/' /etc/my.cnf
# 2. 重啟 MySQL 服務
systemctl restart mysqld
# 或
service mysqld restart
# 3. 驗證
netstat -talnp | grep 3306
# 應顯示 LISTEN 狀態
重啟後 JDBC 連線恢復正常。
| 可能原因 | 檢查方法 | 解決 |
|---|---|---|
| JDBC URL IP/Host/Port 錯誤 | ping host、telnet host 3306 | 修正 URL、用 IP 替代域名 |
| MySQL bind-address 非 0.0.0.0 | cat /etc/my.cnf | grep bind-address | 設為 0.0.0.0 或具體內網 IP |
| skip-networking 開啟 | cat /etc/my.cnf | grep skip-networking | 註釋並重啟 |
| 防火牆/安全組阻擋 3306 | firewall-cmd --list-ports / 雲控制台 | 放行 3306(建議限定來源 IP) |
| MySQL 服務未啟動/崩潰 | systemctl status mysqld / error log | 啟動服務、排查錯誤日誌 |
| 連線池耗盡 / wait_timeout 導致斷連 | show processlist / 監控連線數 | 調整連線池大小、啟用 testWhileIdle、設定 validationQuery |
| JDBC 驅動版本不匹配 | 檢查 pom.xml / classpath 版本 | 升級至與 Server 兼容版本(如 5.1.47 / 8.0.33) |
skip-networking 是「本地能連、遠程不通」的經典隱形殺手。**任何 MySQL 部署上線前,必須驗證 3306 端口監聽狀態**(netstat -talnp | grep 3306)。配置管理應納入版本控制,變更需經過測試環境驗證,避免手動修改配置導致生產故障。