java.net.ConnectException:?Connection?refused報錯的解決方法詳解
前言:一個高頻卻常被誤解的異常
在 Java 企業(yè)級應(yīng)用開發(fā)中,無論是構(gòu)建 Web 后端服務(wù)、微服務(wù)架構(gòu),還是進行數(shù)據(jù)集成與批處理任務(wù),開發(fā)者幾乎不可避免地會遇到如下異常堆棧:
java.net.ConnectException: Connection refused: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.Net.connect(Net.java:578)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:751)
...
該異常通常出現(xiàn)在嘗試建立 TCP 連接時——例如通過 JDBC 連接 MySQL、調(diào)用 RESTful API、連接 Redis 緩存、或與消息隊列(如 RabbitMQ、Kafka)通信。盡管其字面意思看似直白(“連接被拒絕”),但許多開發(fā)者在初次遭遇時仍會陷入困惑:是代碼寫錯了?是網(wǎng)絡(luò)不通?還是服務(wù)宕機了?
一、問題本質(zhì):操作系統(tǒng)層面的“拒絕”信號
1.1 異常來源并非 Java 虛擬機
首先必須明確:java.net.ConnectException 是 Java 對底層操作系統(tǒng)返回錯誤碼的封裝。當(dāng) Java 應(yīng)用調(diào)用 Socket.connect() 方法時,JVM 會委托操作系統(tǒng)內(nèi)核發(fā)起 TCP 連接請求。若內(nèi)核在嘗試建立連接過程中收到特定的網(wǎng)絡(luò)響應(yīng)(如 RST 包),便會向 JVM 返回一個錯誤碼(在 Linux/Unix 系統(tǒng)中為 ECONNREFUSED,在 Windows 中為 WSAECONNREFUSED),JVM 再將其轉(zhuǎn)換為 ConnectException 拋出。
因此,該異常反映的是網(wǎng)絡(luò)層或傳輸層的問題,而非應(yīng)用邏輯錯誤。
1.2 TCP 三次握手中的“拒絕”機制
理解此異常的關(guān)鍵在于掌握 TCP 協(xié)議的行為:
- 當(dāng)客戶端向目標(biāo)主機的某端口發(fā)送 SYN(同步)包以發(fā)起連接時;
- 若目標(biāo)主機的操作系統(tǒng)內(nèi)核發(fā)現(xiàn)沒有任何進程正在監(jiān)聽該端口;
- 內(nèi)核將立即向客戶端回送一個 RST(Reset)包,表示“此端口無服務(wù),請勿重試”;
- 客戶端操作系統(tǒng)收到 RST 后,向上層應(yīng)用(即 Java 程序)報告“Connection refused”。
核心結(jié)論:Connection refused = 目標(biāo)主機可達 + 目標(biāo)端口無服務(wù)監(jiān)聽
這與 Connection timed out(連接超時)有本質(zhì)區(qū)別:
- Timeout:SYN 包發(fā)出后未收到任何響應(yīng)(可能因網(wǎng)絡(luò)中斷、防火墻丟包、主機宕機);
- Refused:SYN 包已送達,但對方明確告知“此處無服務(wù)”。
二、根本原因分類與排查指南
根據(jù)多年工程實踐經(jīng)驗,導(dǎo)致 Connection refused 的原因可歸納為以下五大類。
2.1 服務(wù)進程未啟動(最常見原因)
這是本地開發(fā)、測試環(huán)境中占比最高的原因。服務(wù)未運行,自然無法監(jiān)聽端口。
Windows 系統(tǒng)操作指南
在 Windows 操作系統(tǒng)中,MySQL、PostgreSQL、Redis 等數(shù)據(jù)庫服務(wù)通常以“Windows 服務(wù)”的形式安裝和管理。如果服務(wù)未啟動,則對應(yīng)的端口(如 MySQL 默認 3306)將不會被監(jiān)聽,從而導(dǎo)致 Connection refused 錯誤。
圖形化界面操作步驟(推薦初學(xué)者使用)
打開“服務(wù)”管理控制臺:
- 按下鍵盤上的
Win + R組合鍵,彈出“運行”對話框。 - 在輸入框中鍵入
services.msc,然后按回車鍵或點擊“確定”。 - 此時將打開“服務(wù)”窗口,其中列出了當(dāng)前系統(tǒng)中所有已注冊的服務(wù)。
- 按下鍵盤上的
查找目標(biāo)數(shù)據(jù)庫服務(wù):
- 在服務(wù)列表中,滾動查找名稱包含
MySQL的條目。 - 常見的服務(wù)名稱包括:
MySQL80(MySQL 8.0 版本)MySQL57(MySQL 5.7 版本)MySQL(通用名稱,多見于舊版安裝)MariaDB(MariaDB 數(shù)據(jù)庫)Redis(Redis 服務(wù))
- 如果你不確定具體名稱,可以右鍵點擊任意服務(wù) → “屬性”,查看“路徑到可執(zhí)行文件”字段,確認是否為你安裝的數(shù)據(jù)庫程序。
- 在服務(wù)列表中,滾動查找名稱包含
檢查服務(wù)狀態(tài)并啟動:
- 查看“狀態(tài)”列。如果該列為空白,說明服務(wù)當(dāng)前未運行。
- 右鍵點擊該服務(wù)名稱,在彈出的上下文菜單中選擇“啟動”。
- 啟動成功后,“狀態(tài)”列將顯示為“正在運行”。
- 如果啟動失?。ɡ缣崾?ldquo;錯誤 1067:進程意外終止”),則需進一步檢查數(shù)據(jù)庫的日志文件(通常位于
C:\ProgramData\MySQL\MySQL Server X.X\Data\目錄下的.err文件)。
設(shè)置開機自動啟動(可選):
- 為避免每次重啟電腦后手動啟動服務(wù),可右鍵點擊服務(wù) → “屬性”。
- 在“啟動類型”下拉菜單中選擇“自動”。
- 點擊“應(yīng)用”并“確定”。下次系統(tǒng)啟動時,該服務(wù)將自動運行。
命令行方式(適用于腳本化或高級用戶)
Windows 提供了強大的命令行工具來管理服務(wù),無需依賴圖形界面。
1.列出所有與 MySQL 相關(guān)的服務(wù):
sc queryex type= service state= all | findstr /i "mysql"
sc(Service Control)是 Windows 內(nèi)置的服務(wù)管理命令。- 此命令將輸出所有服務(wù)名中包含“mysql”(不區(qū)分大小寫)的服務(wù)及其狀態(tài)。
2.啟動指定服務(wù):
net start MySQL80
- 將
MySQL80替換為你實際的服務(wù)名稱。 - 成功啟動后,命令行會顯示“MySQL80 服務(wù)正在啟動… MySQL80 服務(wù)已經(jīng)啟動成功。”
3.停止服務(wù):
net stop MySQL80
4.查詢服務(wù)詳細信息:
sc qc MySQL80
此命令可查看服務(wù)的可執(zhí)行文件路徑、依賴關(guān)系、啟動賬戶等關(guān)鍵信息,對排錯非常有幫助。
macOS 系統(tǒng)操作指南
macOS 上的數(shù)據(jù)庫服務(wù)管理方式取決于其安裝途徑。主流方式有兩種:Homebrew(開發(fā)者首選)和 官方 .dmg 安裝包。
A. 通過 Homebrew 安裝的 MySQL(強烈推薦)
Homebrew 是 macOS 上最流行的包管理器,它能自動處理依賴、配置和后臺服務(wù)管理。
檢查 Homebrew 服務(wù)狀態(tài):打開“終端”(Terminal),輸入以下命令:
brew services list
該命令會列出所有由 Homebrew 管理的后臺服務(wù)。
輸出示例:
Name Status User Plist
mysql stopped /Users/yourname/Library/LaunchAgents/homebrew.mxcl.mysql.plist
redis started yourname /Users/yourname/Library/LaunchAgents/homebrew.mxcl.redis.plist
Status 列顯示 stopped 表示服務(wù)未運行。
啟動 MySQL 服務(wù):
# 啟動服務(wù),并設(shè)置為登錄時自動啟動(僅對當(dāng)前用戶) brew services start mysql # 或者,僅啟動一次(不設(shè)為自動啟動) brew services run mysql
start 命令會創(chuàng)建一個 launchd 配置文件(.plist),確保服務(wù)在用戶登錄時自動啟動。
run 命令則只在當(dāng)前終端會話中運行服務(wù),關(guān)閉終端后服務(wù)也會停止。
停止服務(wù):
brew services stop mysql
驗證服務(wù)是否正常運行:
# 檢查 MySQL 進程 ps aux | grep mysqld # 嘗試連接數(shù)據(jù)庫(默認 root 用戶無密碼,首次安裝后建議運行 mysql_secure_installation) mysql -u root
查看日志(排錯必備):Homebrew 安裝的 MySQL 日志通常位于:
cat /opt/homebrew/var/mysql/$(hostname).err # 或 Intel Mac: cat /usr/local/var/mysql/$(hostname).err
B. 通過官方 .dmg 安裝包安裝的 MySQL
這種方式會將 MySQL 安裝到 /usr/local/mysql/ 目錄,并提供一個系統(tǒng)偏好設(shè)置面板。
圖形化啟動方式:
- 打開“系統(tǒng)設(shè)置”(System Settings)或舊版的“系統(tǒng)偏好設(shè)置”(System Preferences)。
- 在底部或側(cè)邊欄找到并點擊 “MySQL” 圖標(biāo)。
- 在彈出的窗口中,你會看到一個大按鈕:“Start MySQL Server”。
- 點擊該按鈕,狀態(tài)會從 “MySQL Server is stopped.” 變?yōu)?“MySQL Server is running.”。
命令行啟動/停止:官方安裝包提供了便捷的腳本:
# 啟動 MySQL sudo /usr/local/mysql/support-files/mysql.server start # 停止 MySQL sudo /usr/local/mysql/support-files/mysql.server stop # 重啟 MySQL sudo /usr/local/mysql/support-files/mysql.server restart # 檢查狀態(tài) sudo /usr/local/mysql/support-files/mysql.server status
- 這些命令本質(zhì)上是調(diào)用了
mysqld_safe腳本來管理進程。 - 注意:需要
sudo權(quán)限,因為服務(wù)通常以_mysql用戶身份運行。
添加 PATH(方便使用 mysql 命令):為了能在任意目錄下直接使用 mysql 命令,需要將 MySQL 的 bin 目錄加入環(huán)境變量。
編輯你的 shell 配置文件(如 ~/.zshrc 或 ~/.bash_profile):
echo 'export PATH="/usr/local/mysql/bin:$PATH"' >> ~/.zshrc source ~/.zshrc
之后即可直接在終端輸入 mysql -u root -p 進行連接。
Linux 系統(tǒng)操作指南
Linux 發(fā)行版眾多,但現(xiàn)代主流發(fā)行版(如 Ubuntu 16.04+、CentOS 7+、Debian 8+)均采用 systemd 作為初始化系統(tǒng)和服務(wù)管理器。舊版系統(tǒng)(如 CentOS 6)則使用 SysV init。
A. 使用 systemd(現(xiàn)代 Linux 發(fā)行版標(biāo)準(zhǔn))
systemd 通過 systemctl 命令統(tǒng)一管理所有系統(tǒng)服務(wù)。
檢查 MySQL 服務(wù)狀態(tài):不同發(fā)行版對 MySQL 服務(wù)的命名略有差異:
執(zhí)行以下命令之一:
# Ubuntu/Debian sudo systemctl status mysql # CentOS/RHEL sudo systemctl status mysqld
Ubuntu/Debian 系:服務(wù)名為 mysql
CentOS/RHEL/Fedora 系:服務(wù)名為 mysqld
關(guān)鍵觀察點:
Active: active (running):服務(wù)正在運行。Active: inactive (dead):服務(wù)已停止。- 如果提示
Unit ... not found,說明 MySQL 未安裝。
啟動、停止、重啟服務(wù):
# 啟動服務(wù) sudo systemctl start mysql # 或 mysqld # 停止服務(wù) sudo systemctl stop mysql # 重啟服務(wù)(修改配置后常用) sudo systemctl restart mysql # 重新加載配置(不中斷服務(wù)) sudo systemctl reload mysql
設(shè)置開機自啟:
# 啟用開機自啟 sudo systemctl enable mysql # 禁用開機自啟 sudo systemctl disable mysql
enable 命令會在 /etc/systemd/system/multi-user.target.wants/ 目錄下創(chuàng)建一個符號鏈接。
查看實時服務(wù)日志(排錯神器):systemd 集成了日志系統(tǒng) journald,可通過以下命令實時跟蹤服務(wù)日志:
# 實時跟蹤 MySQL 服務(wù)日志 sudo journalctl -u mysql -f # 查看最近 100 行日志 sudo journalctl -u mysql -n 100
這比直接查看 /var/log/mysql/error.log 更方便,因為它包含了 systemd 的元數(shù)據(jù)(如時間戳、進程ID)。
B. 使用 SysV init(舊版 Linux 系統(tǒng))
雖然已逐漸被淘汰,但在一些遺留系統(tǒng)中仍會遇到。
檢查服務(wù)狀態(tài):
sudo service mysql status # 或直接調(diào)用 init 腳本 sudo /etc/init.d/mysql status
管理服務(wù):
# 啟動 sudo service mysql start # 停止 sudo service mysql stop # 重啟 sudo service mysql restart
設(shè)置開機自啟:
# Ubuntu/Debian (使用 update-rc.d) sudo update-rc.d mysql defaults # CentOS 6 (使用 chkconfig) sudo chkconfig --level 35 mysql on
2.2 客戶端連接配置錯誤
連接字符串(URL)中的 IP 地址、端口號或協(xié)議寫錯。
常見錯誤示例:
- JDBC URL:
jdbc:mysql://localhost:3360/testdb(端口應(yīng)為3306); - 主機名拼寫錯誤:
locahost、127.0..1; - 使用了錯誤的環(huán)境變量(如
DB_HOST=prod-db但在 dev 環(huán)境運行)。
排查重點:
- 檢查
application.properties/application.yml; - 核對
.env文件或 Kubernetes ConfigMap; - 在 IDE 中打印完整的連接 URL(注意脫敏)。
2.3 服務(wù)綁定地址限制(Bind Address Issue)
服務(wù)雖已啟動,但僅綁定到 127.0.0.1(loopback 接口),拒絕來自外部 IP 的連接。
典型表現(xiàn):
- 本機可通過
127.0.0.1:3306連接 MySQL; - 但從同一局域網(wǎng)的另一臺機器使用
192.168.1.100:3306連接失敗,報Connection refused。
驗證命令(在服務(wù)所在主機執(zhí)行):
ss -tuln | grep :3306 # 或 netstat -tuln | grep :3306
輸出示例:
tcp LISTEN 0 80 127.0.0.1:3306 0.0.0.0:*← 僅本機可連tcp LISTEN 0 80 0.0.0.0:3306 0.0.0.0:*← 所有接口可連
解決方案:
- MySQL:修改
my.cnf(位置通常為/etc/mysql/my.cnf或/etc/my.cnf),在[mysqld]部分添加或修改bind-address = 0.0.0.0,然后重啟服務(wù)。 - Spring Boot:添加
server.address=0.0.0.0到配置文件。 - 自定義服務(wù):確保
ServerSocket綁定到0.0.0.0或具體網(wǎng)卡 IP。
2.4 防火墻或安全組策略攔截
雖然服務(wù)在監(jiān)聽,但網(wǎng)絡(luò)中間設(shè)備阻止了連接請求。
本地防火墻:
Windows:檢查“Windows Defender 防火墻” -> “高級設(shè)置” -> “入站規(guī)則”,確保有允許目標(biāo)端口(如 3306)的規(guī)則。
Linux (UFW):
sudo ufw status verbose sudo ufw allow 3306/tcp
Linux (firewalld):
sudo firewall-cmd --list-ports sudo firewall-cmd --permanent --add-port=3306/tcp sudo firewall-cmd --reload
云平臺安全組(極易被忽視!):
- 阿里云/騰訊云/AWS/Azure:登錄控制臺,找到你的云服務(wù)器實例,進入“安全組”配置頁面。
- 添加一條入站規(guī)則:協(xié)議類型
TCP,端口范圍3306,授權(quán)對象0.0.0.0/0(測試用)或你的辦公 IP。
2.5 容器化環(huán)境網(wǎng)絡(luò)配置問題
在 Docker、Kubernetes 等容器平臺中,網(wǎng)絡(luò)命名空間隔離增加了復(fù)雜性。
Docker 常見問題:
- 未使用
-p參數(shù)映射端口:docker run mysql? vsdocker run -p 3306:3306 mysql?; - 容器間通信使用了宿主機 IP 而非 Docker 自定義網(wǎng)絡(luò)中的服務(wù)名。
Kubernetes 問題:
- Service 的
targetPort與 Pod 實際監(jiān)聽端口不一致; - Pod 未通過 Readiness Probe,Service 未將流量轉(zhuǎn)發(fā);
- NetworkPolicy 限制了跨命名空間通信。
排查命令:
docker ps # 查看運行容器 docker port <container_id> # 檢查端口映射 kubectl get svc,pods -n <namespace> # 查看 K8s 服務(wù)狀態(tài)
三、標(biāo)準(zhǔn)化排查流程(推薦順序)
遵循 “由近及遠、由內(nèi)到外、先服務(wù)后網(wǎng)絡(luò)” 的原則,逐步縮小問題范圍。
步驟 1:確認目標(biāo)服務(wù)是否真正運行并監(jiān)聽端口
操作位置:服務(wù)所在主機
# 檢查進程 ps aux | grep <service_name> # 檢查端口監(jiān)聽(關(guān)鍵?。? ss -tuln | grep :<PORT> # 或 netstat -tuln | grep :<PORT>
- 若無輸出 → 服務(wù)未啟動或未監(jiān)聽該端口 → 啟動服務(wù)。
- 若輸出顯示
127.0.0.1:<PORT>→ 僅本地可連 → 修改綁定地址。
步驟 2:核對客戶端連接配置
操作位置:客戶端代碼/配置文件
- 檢查 JDBC URL、HTTP endpoint、Redis 連接字符串等;
- 確保 IP、端口、協(xié)議(如
jdbc:mysql://)完全正確; - 注意環(huán)境變量覆蓋問題(如
SPRING_DATASOURCE_URL)。
步驟 3:使用telnet或nc測試 TCP 連通性
操作位置:客戶端主機
telnet <IP> <PORT> # 或 nc -vz <IP> <PORT>
- 成功:屏幕變黑或顯示服務(wù) banner(如 MySQL 版本信息);
- Connection refused:服務(wù)未監(jiān)聽(回到步驟 1);
- Timeout:網(wǎng)絡(luò)不通或防火墻攔截(進入步驟 4)。
提示:Windows 可啟用 Telnet 客戶端功能,或使用 PowerShell 命令:
Test-NetConnection -ComputerName 127.0.0.1 -Port 3306
步驟 4:檢查防火墻與云安全組
操作位置:服務(wù)所在主機 + 云控制臺
- 臨時關(guān)閉本地防火墻測試;
- 登錄云平臺控制臺,檢查實例關(guān)聯(lián)的安全組規(guī)則;
- 確保入站規(guī)則允許
<PORT>/TCP來自你的 IP 或0.0.0.0/0(測試用)。
步驟 5:容器環(huán)境專項檢查
操作位置:Docker Host / Kubernetes Cluster
- 確認容器運行狀態(tài):
docker ps/kubectl get pods; - 檢查端口映射:
docker port <id>; - 在容器內(nèi)部測試連接:
docker exec -it <container> telnet 127.0.0.1 <PORT>。
四、預(yù)防措施與工程最佳實踐
4.1 自動化依賴管理
使用 docker-compose.yml 統(tǒng)一管理本地開發(fā)依賴(MySQL、Redis、Elasticsearch 等),避免手動啟停遺漏。
version: '3'
services:
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root4.2 健康檢查與啟動探針
在應(yīng)用啟動時加入數(shù)據(jù)庫連接探針,失敗時提供友好提示:
@PostConstruct
public void checkDatabaseConnection() {
try (Connection conn = dataSource.getConnection()) {
// 成功
} catch (SQLException e) {
log.error("無法連接數(shù)據(jù)庫,請檢查服務(wù)是否啟動及配置是否正確", e);
System.exit(1); // 或拋出自定義異常
}
}
4.3 配置分離與環(huán)境隔離
- 使用 Spring Profiles、Kubernetes ConfigMap/Secrets 管理不同環(huán)境配置;
- 避免硬編碼連接信息,全部通過配置注入。
4.4 日志增強與可觀測性
在捕獲 ConnectException 時,記錄完整的連接目標(biāo)(脫敏后):
log.error("連接 {} 失敗", maskUrl(url), e);集成 APM 工具(如 SkyWalking、Prometheus)監(jiān)控服務(wù)依賴健康狀態(tài)。
4.5 基礎(chǔ)設(shè)施即代碼(IaC)
使用 Terraform、Ansible 管理云資源與安全組,確保網(wǎng)絡(luò)策略可版本化、可審計。
以上就是java.net.ConnectException: Connection refused報錯的解決方法詳解的詳細內(nèi)容,更多關(guān)于java.net.ConnectException報錯解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于Spring實現(xiàn)零重啟自由編排任務(wù)的定時管理器
我們發(fā)現(xiàn),我們使用Spring自帶的定時任務(wù)如果要有修改,那么就要修改代碼,然后重啟項目,所以本文就帶大家實現(xiàn)一個零重啟自由編排任務(wù)的定時管理器吧2023-07-07
利用SpringBoot實現(xiàn)一個基于本地代理模式的RPC調(diào)用框架
雖然Dubbo、gRPC等成熟框架已經(jīng)為我們提供了完整的RPC解決方案,但理解其底層原理并動手實現(xiàn)一個簡化版本,對提升我們的技術(shù)理解深度很有幫助,下面我們就來看看如何使用SpringBoot實現(xiàn)一個基于本地代理模式的RPC調(diào)用框架吧2025-07-07
Spring?Kafka中如何通過參數(shù)配置解決超時問題詳解
這篇文章主要給大家介紹了關(guān)于Spring?Kafka中如何通過參數(shù)配置解決超時問題的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-01-01
迅速學(xué)會@ConfigurationProperties的使用操作
這篇文章主要介紹了迅速學(xué)會@ConfigurationProperties的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
SpringBoot中多個PostConstruct注解執(zhí)行順序控制
本文介紹了SpringBoot中使用多個@PostConstruct注解的方法執(zhí)行順序,以解決ClassA依賴ClassB初始化結(jié)果的問題,具有一定的參考價值,感興趣的可以了解一下2025-08-08

