fix: verify CentOS7 port takeover before fallback

This commit is contained in:
shiyue
2026-08-23 14:08:09 +08:00
parent 265199a48e
commit dd233a40e8

View File

@@ -52,6 +52,38 @@ port_is_open() {
( : >/dev/tcp/127.0.0.1/"${port}" ) 2>/dev/null
}
list_port_pids() {
local port="$1"
if command -v fuser >/dev/null 2>&1; then
fuser -n tcp "${port}" 2>/dev/null || true
return 0
fi
if command -v lsof >/dev/null 2>&1; then
lsof -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true
return 0
fi
if command -v ss >/dev/null 2>&1; then
ss -ltnp 2>/dev/null \
| awk -v port=":${port}" 'NR > 1 && $4 ~ (port "$") { print }' \
| sed -n 's/.*pid=\([0-9][0-9]*\).*/\1/p' \
| sort -u
return 0
fi
if command -v netstat >/dev/null 2>&1; then
netstat -ltnp 2>/dev/null \
| awk -v port=":${port}" 'NR > 2 && $4 ~ (port "$") { print $7 }' \
| sed -n 's#^\([0-9][0-9]*\)/.*#\1#p' \
| sort -u
return 0
fi
return 1
}
wait_for_port() {
local port="$1"
local attempts="${2:-20}"
@@ -68,6 +100,7 @@ wait_for_port() {
stop_port_listener() {
local port="$1"
local pids=""
local kill_mode=""
if ! port_is_open "${port}"; then
log "端口 ${port} 当前未被占用"
@@ -75,18 +108,29 @@ stop_port_listener() {
fi
if command -v fuser >/dev/null 2>&1; then
pids="$(fuser -n tcp "${port}" 2>/dev/null || true)"
log "关闭端口 ${port},占用进程: ${pids:-未知}"
fuser -k -TERM -n tcp "${port}" >/dev/null 2>&1 || true
kill_mode="fuser"
elif command -v lsof >/dev/null 2>&1; then
pids="$(lsof -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true)"
log "关闭端口 ${port},占用进程: ${pids:-未知}"
kill_mode="kill"
elif command -v ss >/dev/null 2>&1 || command -v netstat >/dev/null 2>&1; then
kill_mode="kill"
else
warn "端口 ${port} 被占用,但系统没有 fuser/lsof/ss/netstat无法自动关闭"
return 1
fi
pids="$(list_port_pids "${port}")"
if [[ -z "${pids//[[:space:]]/}" ]]; then
warn "端口 ${port} 被占用,但无法获取占用进程 PID拒绝继续启动以免误报"
return 1
fi
log "关闭端口 ${port},占用进程: ${pids}"
if [[ "${kill_mode}" == "fuser" ]]; then
fuser -k -TERM -n tcp "${port}" >/dev/null 2>&1 || true
else
for pid in ${pids}; do
kill -TERM "${pid}" 2>/dev/null || true
done
else
warn "端口 ${port} 被占用,但系统没有 fuser/lsof无法自动关闭"
return 1
fi
for _ in {1..10}; do
@@ -97,7 +141,7 @@ stop_port_listener() {
done
warn "端口 ${port} 未能在宽限期内释放,尝试强制关闭"
if command -v fuser >/dev/null 2>&1; then
if [[ "${kill_mode}" == "fuser" ]]; then
fuser -k -KILL -n tcp "${port}" >/dev/null 2>&1 || true
else
for pid in ${pids}; do
@@ -451,7 +495,7 @@ ensure_release_binary() {
start_single_exe() {
ensure_release_binary || return 1
stop_port_listener "${PORT_VALUE}" || true
stop_port_listener "${PORT_VALUE}" || return 1
local runtime_log_dir="${CC_WEB_LOGS_DIR:-${RELEASE_DIR}/logs}"
local output_log="${runtime_log_dir}/cc-web-single-exe.out"
@@ -519,7 +563,7 @@ main() {
fi
PORT_VALUE="$(resolve_port)"
stop_port_listener "${PORT_VALUE}" || true
stop_port_listener "${PORT_VALUE}" || fail "无法释放端口 ${PORT_VALUE},已停止启动以避免继续使用旧进程"
case "${START_MODE}" in
single|release|bun)
@@ -547,7 +591,7 @@ $(node_upgrade_hint)"
warn "源码方式启动失败,检测到 CentOS 7回退到 dist-exe single-exe"
stop_existing_pm2_app
stop_port_listener "${PORT_VALUE}" || true
stop_port_listener "${PORT_VALUE}" || fail "无法释放端口 ${PORT_VALUE},已停止回退启动以避免继续使用旧进程"
start_single_exe || fail "CentOS 7 single-exe 启动失败,请检查 ${RELEASE_ENTRY_PATH} 及日志"
log "完成。当前使用 CentOS 7 single-exe。"
}