服務(wù)未就緒,應(yīng)用搶跑?用 wait-for[-it]穩(wěn)住啟動(dòng)節(jié)奏
在實(shí)際的 DevOps 和 CI/CD 流程中,容器或服務(wù)的啟動(dòng)往往并非孤立完成,而是依賴(lài)于數(shù)據(jù)庫(kù)、緩存、API 網(wǎng)關(guān)等其他服務(wù)。如果這些依賴(lài)尚未準(zhǔn)備好,直接啟動(dòng)主應(yīng)用將面臨連接失敗、初始化出錯(cuò)等風(fēng)險(xiǎn)。
為了更可靠地控制服務(wù)的啟動(dòng)順序,本文推薦一個(gè)輕量級(jí)工具 wait-for。該工具專(zhuān)為容器或腳本環(huán)境中等待某個(gè)端口服務(wù)可用而設(shè)計(jì),適用于絕大多數(shù)現(xiàn)代化部署流程。
工具簡(jiǎn)介
wait-for 是一個(gè)用純 sh 編寫(xiě)的腳本工具,無(wú)需額外依賴(lài),可直接在任何類(lèi) Unix 系統(tǒng)中使用。它通過(guò)輪詢(xún)目標(biāo) host:port 的方式,等待服務(wù)監(jiān)聽(tīng)端口成功打開(kāi),從而判斷服務(wù)已經(jīng)就緒。
主要特性包括:
- ? 純 shell 編寫(xiě),無(wú)需編譯或安裝
- ? 支持超時(shí)設(shè)置
- ? 支持目標(biāo)服務(wù)就緒后自動(dòng)執(zhí)行其他命令
- ? 易于集成到 Dockerfile、Kubernetes、CI/CD 等環(huán)境中
安裝與使用
無(wú)需下載腳本文件,直接使用 wget 或 curl 管道即可:
wget -qO- https://raw.githubusercontent.com/eficode/wait-for/v2.2.3/wait-for | sh -s -- host:port -- command
或使用 curl:
curl -s https://raw.githubusercontent.com/eficode/wait-for/v2.2.3/wait-for | sh -s -- host:port -- command
其中 -- 是一個(gè)參數(shù)分隔符,表示后面的內(nèi)容是待執(zhí)行的命令。
使用場(chǎng)景示例
1. 容器啟動(dòng)前等待數(shù)據(jù)庫(kù)就緒
在 docker-compose 項(xiàng)目中,某服務(wù)依賴(lài)于 MySQL,可以在入口腳本中添加:
wait-for db:3306 -- ./start-server.sh
該命令會(huì)阻塞,直到名為 db 的容器監(jiān)聽(tīng)了 3306 端口才會(huì)繼續(xù)執(zhí)行 start-server.sh。
2. CI/CD 流水線中等待依賴(lài)服務(wù)上線
在 GitLab CI 或 Jenkinsfile 腳本中:
wait-for redis.example.com:6379 -- ./run-tests.sh
測(cè)試任務(wù)會(huì)等待 Redis 服務(wù)可用之后再運(yùn)行,避免測(cè)試中出現(xiàn)連接異常。
3. Kubernetes 中作為 InitContainer 使用
在 Kubernetes Pod 的 initContainers 中使用 wait-for 等待另一個(gè)服務(wù):
initContainers:
- name: wait-for-api
image: busybox
command: ['sh', '-c', 'wget -qO- https://raw.githubusercontent.com/eficode/wait-for/v2.2.3/wait-for | sh -s -- api-service:8080']
這樣可以確保主容器在 API 服務(wù)就緒之后再啟動(dòng)。
4. 指定超時(shí)時(shí)間,避免永久阻塞
wait-for -t 30 api.example.com:443 -- echo "API ready"
如果 30 秒內(nèi)目標(biāo)端口未開(kāi)放,腳本將返回失敗狀態(tài),方便腳本捕捉。
參數(shù)說(shuō)明
參數(shù) | 說(shuō)明 |
| 最多等待多少秒,默認(rèn)不超時(shí) |
| 嚴(yán)格模式:等待成功后執(zhí)行命令,如果命令失敗則整體失敗 |
| 安靜模式:不輸出等待過(guò)程的日志信息 |
| 需要等待的主機(jī)和端口組合 |
| 等待成功后執(zhí)行的命令 |
工作原理
wait-for 的實(shí)現(xiàn)非常簡(jiǎn)單,其原理大致如下:
- 持續(xù)嘗試連接指定的 host:port
- 連接成功即認(rèn)為服務(wù)已就緒
- 如果指定了后續(xù)命令,繼續(xù)執(zhí)行;否則退出
其內(nèi)部使用 nc(netcat)或 Bash 自帶的 /dev/tcp 接口進(jìn)行端口探測(cè),無(wú)需安裝任何第三方依賴(lài)。
使用建議
- 建議在使用時(shí)明確設(shè)置超時(shí)時(shí)間(-t 參數(shù)),避免阻塞流程。
- 可與 shell 腳本、Dockerfile、Kubernetes 資源配置靈活結(jié)合。
總結(jié)
wait-for 是一個(gè)輕量、實(shí)用、適用于各種自動(dòng)化場(chǎng)景的小工具。它幫助我們解決了依賴(lài)服務(wù)未就緒導(dǎo)致主服務(wù)異常啟動(dòng)的問(wèn)題,是 CI/CD、容器編排中不可或缺的穩(wěn)態(tài)工具之一。
如果你在構(gòu)建自動(dòng)化流程時(shí),曾遇到“服務(wù)還沒(méi)起來(lái)就被訪問(wèn)”的尷尬,不妨試試 wait-for,讓你的部署流程更加穩(wěn)定、優(yōu)雅、可控。