初始化提交
This commit is contained in:
27
jenkins/流水线配置/go_中转服务/check_port.sh
Normal file
27
jenkins/流水线配置/go_中转服务/check_port.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 检查本地端口是否在指定超时时间内变为可用
|
||||
# 用法: ./check_port.sh <port> [timeout]
|
||||
# 例如: ./check_port.sh 8000 60
|
||||
#
|
||||
|
||||
PORT=${1:-8000}
|
||||
TIMEOUT=${2:-60}
|
||||
INTERVAL=5
|
||||
START_TIME=$(date +%s)
|
||||
END_TIME=$((START_TIME + TIMEOUT))
|
||||
|
||||
echo "开始检测: 端口 $PORT,超时时间 ${TIMEOUT}s,每次间隔 ${INTERVAL}s"
|
||||
|
||||
while [ $(date +%s) -lt $END_TIME ]; do
|
||||
if nc -z -w1 localhost "$PORT" 2>/dev/null; then
|
||||
echo "[$(date '+%F %T')] ✅ 端口 $PORT 已启用"
|
||||
exit 0
|
||||
else
|
||||
echo "[$(date '+%F %T')] ⏳ 端口 $PORT 尚为启动用,等待 ${INTERVAL}s..."
|
||||
sleep $INTERVAL
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[$(date '+%F %T')] ❌ 超时: 端口 $PORT 在 ${TIMEOUT}s 内未变为启用"
|
||||
exit 1
|
||||
170
jenkins/流水线配置/go_中转服务/prod_go_lessie_sourcing_api.conf
Normal file
170
jenkins/流水线配置/go_中转服务/prod_go_lessie_sourcing_api.conf
Normal file
@@ -0,0 +1,170 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
tools{
|
||||
go 'go1.24.0'
|
||||
}
|
||||
|
||||
environment {
|
||||
REMOTE_HOST_A = "43.153.98.191"
|
||||
REMOTE_HOST_B = "49.51.41.243"
|
||||
NGINX_HOST = "49.51.46.148"
|
||||
|
||||
REMOTE_PROJECT_PATH_A = "/data/webapps/go_lessie_sourcing_api"
|
||||
REMOTE_PROJECT_PATH_B = "/data/webapps/go_lessie_sourcing_api"
|
||||
|
||||
|
||||
NGINX_GO_backend_A = "10.0.0.10"
|
||||
NGINX_GO_backend_B = "10.0.0.8"
|
||||
PORT_A = "8100"
|
||||
PORT_B = "8100"
|
||||
|
||||
CONNECTION_TIMEOUT = "600" // 等待连接关闭的超时时间
|
||||
|
||||
CHECK_PORT_SCRIPT = "/data/sh/check_port.sh" // 检查服务所运行的端口是否起起来
|
||||
NGINX_RELOAD_SCRIPT = "/data/sh/set_prod_go_backend_weight.sh" // 设置nginx后端组up/down
|
||||
SEND_STOP_GOAPP_SCRIPT = "/data/sh/send_stop_goapp.sh" // 发送GO的优雅停止信号
|
||||
WAIT_CONNECTIONS_SCRIPT = "/data/sh/wait_for_connections.sh" // 监测实例A是否有连接
|
||||
CHECK_STATUS_SCRIPT = "/data/sh/check_s1_backend_status.sh" // 检查后端组状态
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout 代码') {
|
||||
steps {
|
||||
echo "阶段一"
|
||||
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/go/lessie-sourcing-api.git'
|
||||
}
|
||||
}
|
||||
stage('依赖并构建') {
|
||||
steps {
|
||||
echo "阶段二"
|
||||
sh """
|
||||
cd ${WORKSPACE}/
|
||||
export GOVCS="git.deeplink.media:git,*:git"
|
||||
echo "拉依赖"
|
||||
go mod tidy -v -x
|
||||
echo "构建二进制文件"
|
||||
make build-linux
|
||||
chmod +x ./build/lessie-sourcing-api
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A脱离&下线') {
|
||||
steps {
|
||||
echo "阶段三"
|
||||
echo "将实例A的nginx权重设置为down,停止接收新连接"
|
||||
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_GO_backend_A} ${PORT_A} down'"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
echo "向实例A发送优雅关闭信号"
|
||||
sh ${SEND_STOP_GOAPP_SCRIPT}
|
||||
echo "监测实例A是否有连接"
|
||||
sh ${WAIT_CONNECTIONS_SCRIPT} ${PORT_A} ${CONNECTION_TIMEOUT}
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A同步&启动') {
|
||||
steps {
|
||||
echo "阶段四"
|
||||
sh """
|
||||
echo "进入jenkins工作目录:${WORKSPACE}"
|
||||
cd ${WORKSPACE}/
|
||||
echo "同步二进制产物"
|
||||
rsync -avzuP ./build/lessie-sourcing-api ./configs/application_prod.yaml ${REMOTE_HOST_A}:${REMOTE_PROJECT_PATH_A}/
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
cd ${REMOTE_PROJECT_PATH_A}
|
||||
chmod +x ./lessie-sourcing-api
|
||||
nohup env ENV=prod ./lessie-sourcing-api > ./go.log 2>&1 &
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('探测A服务 ') {
|
||||
steps {
|
||||
echo "阶段五"
|
||||
sh "sleep 10"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
echo "查看实例A的启动日志"
|
||||
head -n 5 ${REMOTE_PROJECT_PATH_A}/go.log || true
|
||||
sh ${CHECK_PORT_SCRIPT} 8100 60
|
||||
ps aux|grep lessie-sourcing-api
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('恢复A流量') {
|
||||
steps {
|
||||
echo "阶段六"
|
||||
echo "恢复实例A的流量"
|
||||
sh "sleep 5"
|
||||
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_GO_backend_A} ${PORT_A} up'"
|
||||
echo "实例 A 部署完成"
|
||||
}
|
||||
}
|
||||
stage('B脱离后端组') {
|
||||
steps {
|
||||
echo "阶段七"
|
||||
echo "将实例B的nginx权重设置为down,停止接收新连接"
|
||||
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_GO_backend_B} ${PORT_B} down'"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_B} '
|
||||
echo "向实例B发送优雅关闭信号"
|
||||
sh ${SEND_STOP_GOAPP_SCRIPT}
|
||||
echo "监测实例B是否有连接"
|
||||
sh ${WAIT_CONNECTIONS_SCRIPT} ${PORT_B} ${CONNECTION_TIMEOUT}
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('B同步&启动') {
|
||||
steps {
|
||||
echo "阶段八"
|
||||
sh """
|
||||
echo "进入jenkins工作目录:${WORKSPACE}"
|
||||
cd ${WORKSPACE}/
|
||||
echo "同步二进制产物"
|
||||
rsync -avzuP ./build/lessie-sourcing-api ./configs/application_prod.yaml ${REMOTE_HOST_B}:${REMOTE_PROJECT_PATH_B}/
|
||||
ssh ${REMOTE_HOST_B} '
|
||||
cd ${REMOTE_PROJECT_PATH_B}
|
||||
chmod +x ./lessie-sourcing-api
|
||||
nohup env ENV=prod ./lessie-sourcing-api > ./go.log 2>&1 &
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('探测B服务 ') {
|
||||
steps {
|
||||
echo "阶段九"
|
||||
echo "探测B服务"
|
||||
sh "sleep 10"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_B} '
|
||||
echo "查看实例B的启动日志"
|
||||
head -n 5 ${REMOTE_PROJECT_PATH_B}/go.log || true
|
||||
sh ${CHECK_PORT_SCRIPT} 8100 60
|
||||
ps aux|grep lessie-sourcing-api
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('恢复B流量') {
|
||||
steps {
|
||||
echo "阶段十"
|
||||
echo "恢复实例A的流量"
|
||||
sh "sleep 5"
|
||||
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_GO_backend_B} ${PORT_B} up'"
|
||||
echo "实例 B 部署完成"
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
echo '✅ 部署成功!'
|
||||
}
|
||||
failure {
|
||||
echo '❌ 部署失败,请检查日志!'
|
||||
}
|
||||
}
|
||||
}
|
||||
97
jenkins/流水线配置/go_中转服务/s1_go_lessie_sourcing_api.conf
Normal file
97
jenkins/流水线配置/go_中转服务/s1_go_lessie_sourcing_api.conf
Normal file
@@ -0,0 +1,97 @@
|
||||
pipeline {
|
||||
agent any
|
||||
tools{
|
||||
go 'go1.23.0'
|
||||
}
|
||||
environment {
|
||||
REMOTE_HOST_A = "43.130.56.138"
|
||||
REMOTE_PROJECT_PATH_A = "/data/webapps/go_lessie_sourcing_api"
|
||||
PORT_A = "8100"
|
||||
CONNECTION_TIMEOUT = "600" // 等待连接关闭的超时时间
|
||||
CHECK_PORT_SCRIPT = "/data/sh/check_port.sh" // 检查服务所运行的端口是否起起来
|
||||
SEND_STOP_GOAPP_SCRIPT = "/data/sh/send_stop_goapp.sh" // 发送GO的优雅停止信号
|
||||
WAIT_CONNECTIONS_SCRIPT = "/data/sh/wait_for_connections.sh" // 监测实例A是否有连接
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout代码') {
|
||||
steps {
|
||||
echo "阶段一"
|
||||
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/go/lessie-sourcing-api.git'
|
||||
}
|
||||
}
|
||||
stage('依赖&构建') {
|
||||
steps {
|
||||
echo "阶段二"
|
||||
sh """
|
||||
cd ${WORKSPACE}/
|
||||
export GOVCS="git.deeplink.media:git,*:git"
|
||||
echo "拉依赖"
|
||||
go mod tidy -v -x
|
||||
echo "构建二进制文件"
|
||||
make build-linux
|
||||
chmod +x ./build/lessie-sourcing-api
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A同步') {
|
||||
steps {
|
||||
echo "阶段三"
|
||||
sh """
|
||||
echo "进入jenkins工作目录:${WORKSPACE}"
|
||||
cd ${WORKSPACE}/
|
||||
echo "同步二进制产物"
|
||||
rsync -avzuP ./build/lessie-sourcing-api ./configs/application_s1.yaml ${REMOTE_HOST_A}:${REMOTE_PROJECT_PATH_A}/
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A下线') {
|
||||
steps {
|
||||
echo "阶段三"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
echo "向实例A发送优雅关闭信号"
|
||||
sh ${SEND_STOP_GOAPP_SCRIPT}
|
||||
echo "监测实例A是否有连接"
|
||||
sh ${WAIT_CONNECTIONS_SCRIPT} ${PORT_A} ${CONNECTION_TIMEOUT}
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A启动') {
|
||||
steps {
|
||||
echo "阶段四"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
cd ${REMOTE_PROJECT_PATH_A}
|
||||
chmod +x ./lessie-sourcing-api
|
||||
nohup env ENV=s1 ./lessie-sourcing-api > ./go.log 2>&1 &
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('探测A服务 ') {
|
||||
steps {
|
||||
echo "阶段五"
|
||||
sh "sleep 10"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
echo "查看实例A的启动日志"
|
||||
head -n 5 ${REMOTE_PROJECT_PATH_A}/go.log || true
|
||||
sh ${CHECK_PORT_SCRIPT} 8100 60
|
||||
sleep 5
|
||||
ps aux|grep lessie-sourcing-api
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
echo '✅ 部署成功!'
|
||||
}
|
||||
failure {
|
||||
echo '❌ 部署失败,请检查日志!'
|
||||
}
|
||||
}
|
||||
}
|
||||
97
jenkins/流水线配置/go_中转服务/s2_go_lessie_sourcing_api.conf
Normal file
97
jenkins/流水线配置/go_中转服务/s2_go_lessie_sourcing_api.conf
Normal file
@@ -0,0 +1,97 @@
|
||||
pipeline {
|
||||
agent any
|
||||
tools{
|
||||
go 'go1.24.0'
|
||||
}
|
||||
environment {
|
||||
REMOTE_HOST_A = "43.159.145.241"
|
||||
REMOTE_PROJECT_PATH_A = "/data/webapps/go_lessie_sourcing_api"
|
||||
PORT_A = "8100"
|
||||
CONNECTION_TIMEOUT = "600" // 等待连接关闭的超时时间
|
||||
CHECK_PORT_SCRIPT = "/data/sh/check_port.sh" // 检查服务所运行的端口是否起起来
|
||||
SEND_STOP_GOAPP_SCRIPT = "/data/sh/send_stop_goapp.sh" // 发送GO的优雅停止信号
|
||||
WAIT_CONNECTIONS_SCRIPT = "/data/sh/wait_for_connections.sh" // 监测实例A是否有连接
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout代码') {
|
||||
steps {
|
||||
echo "阶段一"
|
||||
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/go/lessie-sourcing-api.git'
|
||||
}
|
||||
}
|
||||
stage('依赖&构建') {
|
||||
steps {
|
||||
echo "阶段二"
|
||||
sh """
|
||||
cd ${WORKSPACE}/
|
||||
export GOVCS="git.deeplink.media:git,*:git"
|
||||
echo "拉依赖"
|
||||
go mod tidy -v -x
|
||||
echo "构建二进制文件"
|
||||
make build-linux
|
||||
chmod +x ./build/lessie-sourcing-api
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A同步') {
|
||||
steps {
|
||||
echo "阶段三"
|
||||
sh """
|
||||
echo "进入jenkins工作目录:${WORKSPACE}"
|
||||
cd ${WORKSPACE}/
|
||||
echo "同步二进制产物"
|
||||
rsync -avzuP ./build/lessie-sourcing-api ./configs/application_s2.yaml ${REMOTE_HOST_A}:${REMOTE_PROJECT_PATH_A}/
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A下线') {
|
||||
steps {
|
||||
echo "阶段三"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
echo "向实例A发送优雅关闭信号"
|
||||
sh ${SEND_STOP_GOAPP_SCRIPT}
|
||||
echo "监测实例A是否有连接"
|
||||
sh ${WAIT_CONNECTIONS_SCRIPT} ${PORT_A} ${CONNECTION_TIMEOUT}
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('A启动') {
|
||||
steps {
|
||||
echo "阶段四"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
cd ${REMOTE_PROJECT_PATH_A}
|
||||
chmod +x ./lessie-sourcing-api
|
||||
nohup env ENV=s2 ./lessie-sourcing-api > ./go.log 2>&1 &
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('探测A服务 ') {
|
||||
steps {
|
||||
echo "阶段五"
|
||||
sh "sleep 10"
|
||||
sh """
|
||||
ssh ${REMOTE_HOST_A} '
|
||||
echo "查看实例A的启动日志"
|
||||
head -n 5 ${REMOTE_PROJECT_PATH_A}/go.log || true
|
||||
sh ${CHECK_PORT_SCRIPT} 8100 60
|
||||
sleep 5
|
||||
ps aux|grep lessie-sourcing-api
|
||||
'
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
echo '✅ 部署成功!'
|
||||
}
|
||||
failure {
|
||||
echo '❌ 部署失败,请检查日志!'
|
||||
}
|
||||
}
|
||||
}
|
||||
76
jenkins/流水线配置/go_中转服务/send_stop_goapp.sh
Normal file
76
jenkins/流水线配置/go_中转服务/send_stop_goapp.sh
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
# 线上的 =========================================================
|
||||
#!/bin/bash
|
||||
|
||||
APP_NAME="lessie-sourcing-api"
|
||||
MAX_WAIT_SECONDS=600
|
||||
|
||||
# 1. 获取 PID
|
||||
PID=$(ps -ef | grep "${APP_NAME}" | grep -v grep | awk '{print $2}' | head -n 1)
|
||||
|
||||
if [ -z "$PID" ]; then
|
||||
echo "未找到 ${APP_NAME} 进程,无需停止"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "找到进程 PID: $PID"
|
||||
|
||||
# 2. 发送 SIGTERM
|
||||
kill -TERM $PID
|
||||
echo "已发送 SIGTERM"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# # 3. 等待退出
|
||||
# ELAPSED=0
|
||||
# while [ $ELAPSED -lt $MAX_WAIT_SECONDS ]; do
|
||||
# if ! ps -p $PID > /dev/null 2>&1; then
|
||||
# echo "进程已退出"
|
||||
# exit 0
|
||||
# fi
|
||||
# sleep 10
|
||||
# ELAPSED=$((ELAPSED+10))
|
||||
# echo "已等待 ${ELAPSED} 秒..."
|
||||
# done
|
||||
|
||||
# # 4. 超时强杀
|
||||
# echo "超时 ${MAX_WAIT_SECONDS} 秒未退出,强制 kill -9"
|
||||
# kill -9 $PID
|
||||
|
||||
# ps aux|grep $PID
|
||||
|
||||
|
||||
# s2的===================================================
|
||||
#!/bin/bash
|
||||
APP_PATTERN="./lessie-sourcing-api$"
|
||||
|
||||
PID=$(pgrep -f "$APP_PATTERN")
|
||||
|
||||
if [ -z "$PID" ]; then
|
||||
echo "未找到 lessie-sourcing-api 进程"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "找到 PID: $PID"
|
||||
kill -TERM $PID
|
||||
echo "已发送 SIGTERM"
|
||||
|
||||
|
||||
|
||||
# s3的===================================================
|
||||
#!/bin/bash
|
||||
APP_PATTERN="./s3-lessie-sourcing-api"
|
||||
|
||||
PID=$(pgrep -f "$APP_PATTERN")
|
||||
|
||||
if [ -z "$PID" ]; then
|
||||
echo "未找到 s3-lessie-sourcing-api 进程"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "找到 PID: $PID"
|
||||
kill -TERM $PID
|
||||
echo "已发送 SIGTERM"
|
||||
|
||||
45
jenkins/流水线配置/go_中转服务/set_prod_go_backend_weight.sh
Normal file
45
jenkins/流水线配置/go_中转服务/set_prod_go_backend_weight.sh
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
# Nginx 后端服务器上下线脚本
|
||||
# 用法: set_backend_status.sh <ip> <port> <action>
|
||||
# 示例:
|
||||
# set_backend_status.sh 10.0.0.5 7001 down
|
||||
# set_backend_status.sh 10.0.0.5 7001 up
|
||||
|
||||
IP=$1
|
||||
PORT=$2
|
||||
ACTION=$3 # down / up
|
||||
NGINX_CONFIG="/data/tengine/vhosts/app.lessie.ai.conf"
|
||||
BACKUP_CONFIG="${NGINX_CONFIG}.backup.$(date +%F_%T).bak"
|
||||
|
||||
# 参数检查
|
||||
if [ -z "$IP" ] || [ -z "$PORT" ] || [ -z "$ACTION" ]; then
|
||||
echo "用法: $0 <ip> <port> <action> (action: down/up)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 备份
|
||||
cp -f "$NGINX_CONFIG" "$BACKUP_CONFIG" || {
|
||||
echo "备份配置失败"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 修改
|
||||
if [ "$ACTION" == "down" ]; then
|
||||
sed -i "s/\(server[[:space:]]\+$IP:$PORT[[:space:]]*\)weight=[0-9]\+\(.*\)/\1down\2/" "$NGINX_CONFIG"
|
||||
elif [ "$ACTION" == "up" ]; then
|
||||
sed -i "s/\(server[[:space:]]\+$IP:$PORT[[:space:]]*\)down\(.*\)/\1weight=10\2/" "$NGINX_CONFIG"
|
||||
else
|
||||
echo "无效的 action: $ACTION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 验证 & 重载
|
||||
if nginx -t; then
|
||||
nginx -s reload
|
||||
echo "✅ 已将 $IP:$PORT 设置为 $ACTION"
|
||||
rm -f "$BACKUP_CONFIG"
|
||||
else
|
||||
echo "❌ 配置检查失败,回滚..."
|
||||
cp -f "$BACKUP_CONFIG" "$NGINX_CONFIG"
|
||||
exit 1
|
||||
fi
|
||||
264
jenkins/流水线配置/go_中转服务/wait_for_connections.sh
Normal file
264
jenkins/流水线配置/go_中转服务/wait_for_connections.sh
Normal file
@@ -0,0 +1,264 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 等待指定端口的连接数连续3次为0(每次间隔5秒)
|
||||
# 使用方法: wait_s1_for_connections.sh <port> <timeout>
|
||||
# 示例: wait_s1_for_connections.sh 8000 300(最多等待300秒)
|
||||
|
||||
PORT=$1
|
||||
TIMEOUT=$2
|
||||
START_TIME=$(date +%s)
|
||||
END_TIME=$((START_TIME + TIMEOUT))
|
||||
SUCCESS_COUNT=0 # 连续成功计数
|
||||
REQUIRED_SUCCESS=3 # 需要连续成功的次数
|
||||
CHECK_INTERVAL=5 # 每次检测间隔(秒)
|
||||
|
||||
if [ -z "$PORT" ]; then
|
||||
echo "用法: $0 <port> <timeout>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$TIMEOUT" ]; then
|
||||
TIMEOUT=600 # 默认超时时间600秒
|
||||
fi
|
||||
|
||||
echo "等待端口 $PORT 的连接数连续 $REQUIRED_SUCCESS 次为0(每次检测间隔 $CHECK_INTERVAL 秒),超时时间 $TIMEOUT 秒"
|
||||
|
||||
while [ $(date +%s) -lt $END_TIME ]; do
|
||||
# 检测当前连接数
|
||||
CONNECTIONS=$(netstat -anp | grep :$PORT | grep ESTABLISHED | wc -l)
|
||||
echo "当前连接数: $CONNECTIONS(检测次数: $SUCCESS_COUNT/$REQUIRED_SUCCESS)"
|
||||
|
||||
if [ "$CONNECTIONS" -eq 0 ]; then
|
||||
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
||||
echo "检测到连接数为0,连续成功计数: $SUCCESS_COUNT/$REQUIRED_SUCCESS"
|
||||
|
||||
# 达到3次连续成功,退出
|
||||
if [ "$SUCCESS_COUNT" -eq "$REQUIRED_SUCCESS" ]; then
|
||||
echo "已连续 $REQUIRED_SUCCESS 次(每次间隔 $CHECK_INTERVAL 秒)检测到端口 $PORT 无活跃连接"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
# 连接数不为0,重置计数器
|
||||
SUCCESS_COUNT=0
|
||||
echo "连接数不为0,重置连续成功计数"
|
||||
fi
|
||||
|
||||
# 每次检测后间隔5秒
|
||||
echo "等待 $CHECK_INTERVAL 秒后进行下一次检测..."
|
||||
echo "======================"
|
||||
sleep $CHECK_INTERVAL
|
||||
done
|
||||
|
||||
echo "超时! 端口 $PORT 在 $TIMEOUT 秒内未达到连续 $REQUIRED_SUCCESS 次连接数为0,当前连接数: $CONNECTIONS"
|
||||
exit 1
|
||||
|
||||
|
||||
# === 8月11日 === ↓ ===增加了连接类型过滤和进程实际请求检测======= ↓ =======================================
|
||||
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# 等待AI进程的活跃用户连接为0(排除内部连接和无效连接)
|
||||
# 使用方法: wait_for_ai_connections.sh <port> <process_name> <timeout>
|
||||
# 示例: wait_for_ai_connections.sh 8000 "python server.py" 300
|
||||
# netstat -anp | grep :8000 | grep ESTABLISHED | wc -l
|
||||
|
||||
PORT=$1
|
||||
PROCESS_NAME=$2 # 进程特征名称,用于精准定位
|
||||
TIMEOUT=${3:-300} # 默认超时时间300秒
|
||||
|
||||
# 参数校验
|
||||
if [ -z "$PORT" ] || [ -z "$PROCESS_NAME" ]; then
|
||||
echo "用法: $0 <port> <process_name> <timeout>"
|
||||
echo "示例: $0 8000 'python server.py' 300"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 配置参数
|
||||
START_TIME=$(date +%s)
|
||||
END_TIME=$((START_TIME + TIMEOUT))
|
||||
SUCCESS_COUNT=0
|
||||
REQUIRED_SUCCESS=3 # 连续3次检测通过
|
||||
CHECK_INTERVAL=5 # 检测间隔(秒)
|
||||
NGINX_IP=$(hostname -I | awk '{print $1}') # Nginx服务器IP(排除自身连接)
|
||||
|
||||
echo "开始检测端口 $PORT 上的进程 '$PROCESS_NAME',超时时间 $TIMEOUT 秒"
|
||||
echo "将排除与Nginx服务器($NGINX_IP)的内部连接"
|
||||
|
||||
# 获取进程ID(用于更精准的连接检测)
|
||||
PID=$(ps aux | grep -v grep | grep "$PROCESS_NAME" | grep ":$PORT" | awk '{print $2}')
|
||||
if [ -z "$PID" ]; then
|
||||
echo "未找到端口 $PORT 上的进程 '$PROCESS_NAME'"
|
||||
exit 1
|
||||
fi
|
||||
echo "检测到目标进程PID: $PID"
|
||||
|
||||
while [ $(date +%s) -lt $END_TIME ]; do
|
||||
# 1. 检测活跃连接(排除Nginx内部连接和TIME_WAIT状态)
|
||||
# 过滤条件:
|
||||
# - 状态为ESTABLISHED
|
||||
# - 不包含Nginx服务器IP(排除负载均衡器的健康检查连接)
|
||||
# - 属于目标进程PID
|
||||
CONNECTIONS=$(netstat -antp | grep -E ":$PORT.*ESTABLISHED" | grep -v "$NGINX_IP" | grep "$PID" | wc -l)
|
||||
|
||||
# 2. 检测进程是否有近期请求日志(如果日志有时间戳)
|
||||
# 检查最近30秒内是否有新请求
|
||||
RECENT_LOGS=0
|
||||
LOG_FILE=$(find /data/webapps/ -name "lessie_sourcing_agents_*.log" | sort -r | head -1)
|
||||
if [ -n "$LOG_FILE" ]; then
|
||||
RECENT_LOGS=$(tail -n 100 "$LOG_FILE" | grep -E "$(date -d '30 seconds ago' +'%Y-%m-%d %H:%M:%S')" -A 100 | grep -i "request" | wc -l)
|
||||
fi
|
||||
|
||||
echo "=== 检测结果 ==="
|
||||
echo "活跃用户连接数: $CONNECTIONS(排除Nginx内部连接)"
|
||||
echo "最近30秒请求数: $RECENT_LOGS"
|
||||
echo "连续无连接计数: $SUCCESS_COUNT/$REQUIRED_SUCCESS"
|
||||
echo "================="
|
||||
|
||||
# 判断条件:无活跃连接且无近期请求
|
||||
if [ "$CONNECTIONS" -eq 0 ] && [ "$RECENT_LOGS" -eq 0 ]; then
|
||||
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
||||
if [ "$SUCCESS_COUNT" -eq "$REQUIRED_SUCCESS" ]; then
|
||||
echo "已确认进程无活跃用户连接,安全下线"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
SUCCESS_COUNT=0
|
||||
fi
|
||||
|
||||
sleep $CHECK_INTERVAL
|
||||
done
|
||||
|
||||
echo "超时! 进程仍有活动(连接数: $CONNECTIONS,近期请求: $RECENT_LOGS)"
|
||||
exit 1
|
||||
|
||||
|
||||
|
||||
|
||||
# -------------------------
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# 等待指定端口的连接数连续3次为0(每次间隔5秒)
|
||||
# 使用方法: wait_s1_for_connections.sh <port> <timeout>
|
||||
# 示例: wait_s1_for_connections.sh 8000 300(最多等待300秒)
|
||||
|
||||
PORT=$1
|
||||
TIMEOUT=$2
|
||||
START_TIME=$(date +%s)
|
||||
END_TIME=$((START_TIME + TIMEOUT))
|
||||
SUCCESS_COUNT=0 # 连续成功计数
|
||||
REQUIRED_SUCCESS=5 # 需要连续成功的次数
|
||||
CHECK_INTERVAL=5 # 每次检测间隔(秒)
|
||||
|
||||
if [ -z "$PORT" ]; then
|
||||
echo "用法: $0 <port> <timeout>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$TIMEOUT" ]; then
|
||||
TIMEOUT=600 # 默认超时时间600秒
|
||||
fi
|
||||
|
||||
echo "等待端口 $PORT 的连接数连续 $REQUIRED_SUCCESS 次为0(每次检测间隔 $CHECK_INTERVAL 秒),超时时间 $TIMEOUT 秒"
|
||||
|
||||
while [ $(date +%s) -lt $END_TIME ]; do
|
||||
# 检测当前连接数
|
||||
CONNECTIONS=$(netstat -anp | grep :$PORT | grep -w ESTABLISHED | wc -l)
|
||||
echo "当前连接数: $CONNECTIONS(检测次数: $SUCCESS_COUNT/$REQUIRED_SUCCESS)"
|
||||
|
||||
if [ "$CONNECTIONS" -eq 0 ]; then
|
||||
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
||||
echo "检测到连接数为0,连续成功计数: $SUCCESS_COUNT/$REQUIRED_SUCCESS"
|
||||
|
||||
# 达到3次连续成功,退出
|
||||
if [ "$SUCCESS_COUNT" -eq "$REQUIRED_SUCCESS" ]; then
|
||||
echo "已连续 $REQUIRED_SUCCESS 次(每次间隔 $CHECK_INTERVAL 秒)检测到端口 $PORT 无活跃连接"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
# 连接数不为0,重置计数器
|
||||
SUCCESS_COUNT=0
|
||||
echo "连接数不为0,重置连续成功计数"
|
||||
fi
|
||||
|
||||
# 每次检测后间隔5秒
|
||||
echo "等待 $CHECK_INTERVAL 秒后进行下一次检测..."
|
||||
echo " "
|
||||
sleep $CHECK_INTERVAL
|
||||
done
|
||||
|
||||
echo "超时! 端口 $PORT 在 $TIMEOUT 秒内未达到连续 $REQUIRED_SUCCESS 次连接数为0,当前连接数: $CONNECTIONS"
|
||||
exit 1
|
||||
|
||||
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
|
||||
#!/bin/bash
|
||||
#
|
||||
# 等待指定端口的连接数连续 N 次为 0(每次间隔 M 秒)
|
||||
# 用法: wait_for_connections.sh <port> [timeout]
|
||||
# 示例: wait_for_connections.sh 8000 300 # 最多等待 300 秒
|
||||
#
|
||||
|
||||
PORT=$1
|
||||
TIMEOUT=${2:-600} # 默认超时 600 秒
|
||||
REQUIRED_SUCCESS=${REQUIRED_SUCCESS:-5} # 需要连续成功次数,默认 5 次
|
||||
CHECK_INTERVAL=${CHECK_INTERVAL:-5} # 检测间隔,默认 5 秒
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
END_TIME=$((START_TIME + TIMEOUT))
|
||||
SUCCESS_COUNT=0
|
||||
|
||||
if [ -z "$PORT" ]; then
|
||||
echo "用法: $0 <port> [timeout]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检测可用工具
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
NET_TOOL="ss"
|
||||
elif command -v netstat >/dev/null 2>&1; then
|
||||
NET_TOOL="netstat"
|
||||
else
|
||||
echo "错误: 没有找到 ss 或 netstat 命令"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 获取当前端口 ESTABLISHED 连接数
|
||||
get_connections() {
|
||||
if [ "$NET_TOOL" = "ss" ]; then
|
||||
ss -tanp 2>/dev/null | grep ":$PORT" | grep ESTAB | wc -l
|
||||
else
|
||||
netstat -anp 2>/dev/null | grep ":$PORT" | grep -w ESTABLISHED | wc -l
|
||||
fi
|
||||
}
|
||||
|
||||
echo "开始检测: 端口 $PORT"
|
||||
echo "条件: 连续 $REQUIRED_SUCCESS 次为 0,检测间隔 ${CHECK_INTERVAL}s,超时时间 ${TIMEOUT}s"
|
||||
echo "使用工具: $NET_TOOL"
|
||||
echo "---------------------------------------------"
|
||||
|
||||
while [ $(date +%s) -lt $END_TIME ]; do
|
||||
CONNECTIONS=$(get_connections)
|
||||
TIMESTAMP=$(date '+%F %T')
|
||||
echo "[$TIMESTAMP] 当前连接数: $CONNECTIONS(连续成功 $SUCCESS_COUNT/$REQUIRED_SUCCESS)"
|
||||
|
||||
if [ "$CONNECTIONS" -eq 0 ]; then
|
||||
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
||||
if [ "$SUCCESS_COUNT" -ge "$REQUIRED_SUCCESS" ]; then
|
||||
echo "[$TIMESTAMP] ✅ 检测通过: 端口 $PORT 已连续 $REQUIRED_SUCCESS 次无活跃连接"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
SUCCESS_COUNT=0
|
||||
fi
|
||||
|
||||
sleep "$CHECK_INTERVAL"
|
||||
done
|
||||
|
||||
TIMESTAMP=$(date '+%F %T')
|
||||
echo "[$TIMESTAMP] ❌ 超时: 在 ${TIMEOUT}s 内端口 $PORT 未达到连续 $REQUIRED_SUCCESS 次无活跃连接"
|
||||
exit 1
|
||||
Reference in New Issue
Block a user