fix(deploy): detect service port with ss
This commit is contained in:
+53
-15
@@ -13,6 +13,7 @@ CURRENT_BRANCH=""
|
||||
START_PORT=""
|
||||
BUILD_EXIT=0
|
||||
STOP_WAIT_SECONDS=3
|
||||
STOP_VERIFY_RETRIES=3
|
||||
|
||||
resolve_repo_context() {
|
||||
GIT_DIR_ABS="$(git rev-parse --absolute-git-dir 2>/dev/null)"
|
||||
@@ -106,19 +107,55 @@ run_build() {
|
||||
|
||||
# ============================================================
|
||||
# 6. stop_existing_next —— 强杀当前分支端口上的旧进程
|
||||
# 1) 查找占用 START_PORT 的进程
|
||||
# 1) 使用 ss 查找占用 START_PORT 的进程
|
||||
# 2) 直接 SIGKILL,避免旧服务 drain 太久导致新服务无法绑定端口
|
||||
# 3) 等待 STOP_WAIT_SECONDS,让系统释放端口
|
||||
# 4) 复查端口占用并再次强杀残留
|
||||
# 4) 循环复查端口占用并再次强杀残留
|
||||
# ============================================================
|
||||
find_port_pids() {
|
||||
if command -v lsof >/dev/null 2>&1; then
|
||||
lsof -ti tcp:"$START_PORT" 2>/dev/null || true
|
||||
return
|
||||
if ! command -v ss >/dev/null 2>&1; then
|
||||
echo "=== ss command not found; cannot inspect port $START_PORT ===" >> "$LOG_FILE"
|
||||
return 0
|
||||
fi
|
||||
if command -v fuser >/dev/null 2>&1; then
|
||||
fuser "$START_PORT"/tcp 2>/dev/null || true
|
||||
|
||||
ss -tulnp 2>/dev/null \
|
||||
| awk -v port=":$START_PORT" '$5 ~ port "$" { print }' \
|
||||
| sed -n 's/.*pid=\([0-9][0-9]*\).*/\1/p' \
|
||||
| sort -u
|
||||
}
|
||||
|
||||
force_kill_pids() {
|
||||
PIDS_TO_KILL="$1"
|
||||
if [ -z "$PIDS_TO_KILL" ]; then
|
||||
return 0
|
||||
fi
|
||||
echo "=== force kill PIDS: $PIDS_TO_KILL ===" >> "$LOG_FILE"
|
||||
kill -9 $PIDS_TO_KILL 2>/dev/null || true
|
||||
}
|
||||
|
||||
wait_for_port_release() {
|
||||
RETRY=0
|
||||
while [ "$RETRY" -lt "$STOP_VERIFY_RETRIES" ]; do
|
||||
REMAINING_PIDS="$(find_port_pids)"
|
||||
if [ -z "$REMAINING_PIDS" ]; then
|
||||
echo "=== port $START_PORT released ===" >> "$LOG_FILE"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "=== port $START_PORT still busy, retry=$RETRY, pids=$REMAINING_PIDS ===" >> "$LOG_FILE"
|
||||
force_kill_pids "$REMAINING_PIDS"
|
||||
sleep "$STOP_WAIT_SECONDS"
|
||||
RETRY=$((RETRY + 1))
|
||||
done
|
||||
|
||||
REMAINING_PIDS="$(find_port_pids)"
|
||||
if [ -n "$REMAINING_PIDS" ]; then
|
||||
echo "=== stop FAILED: port $START_PORT still occupied by PIDS: $REMAINING_PIDS ===" >> "$LOG_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "=== port $START_PORT released ===" >> "$LOG_FILE"
|
||||
return 0
|
||||
}
|
||||
|
||||
stop_existing_next() {
|
||||
@@ -126,23 +163,22 @@ stop_existing_next() {
|
||||
PIDS="$(find_port_pids)"
|
||||
|
||||
if [ -n "$PIDS" ]; then
|
||||
echo "=== force kill PIDS: $PIDS ===" >> "$LOG_FILE"
|
||||
kill -9 $PIDS 2>/dev/null || true
|
||||
force_kill_pids "$PIDS"
|
||||
else
|
||||
echo "=== no process found on port $START_PORT ===" >> "$LOG_FILE"
|
||||
fi
|
||||
|
||||
sleep "$STOP_WAIT_SECONDS"
|
||||
|
||||
REMAINING_PIDS="$(find_port_pids)"
|
||||
if [ -n "$REMAINING_PIDS" ]; then
|
||||
echo "=== force kill remaining PIDS: $REMAINING_PIDS ===" >> "$LOG_FILE"
|
||||
kill -9 $REMAINING_PIDS 2>/dev/null || true
|
||||
sleep "$STOP_WAIT_SECONDS"
|
||||
if ! wait_for_port_release; then
|
||||
echo "=== stop ABORT @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
|
||||
echo "" >> "$LOG_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "=== stop DONE @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
|
||||
echo "" >> "$LOG_FILE"
|
||||
return 0
|
||||
}
|
||||
|
||||
launch_next() {
|
||||
@@ -177,7 +213,9 @@ main() {
|
||||
exit $BUILD_EXIT # build 失败 → 不启 start(避免用旧 .next 跑新代码)
|
||||
fi
|
||||
|
||||
stop_existing_next # build 成功 → 先关旧进程
|
||||
if ! stop_existing_next; then
|
||||
exit 1 # 端口未释放 → 不启动新服务,避免 EADDRINUSE
|
||||
fi
|
||||
launch_next # 再启新
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user