Files
2025-11-20 14:54:26 +08:00

942 lines
33 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

pipeline {
agent any
environment {
CODE_BRANCH = "dev"
LOCKHOST_IP = "192.168.70.15"
LOCKHOST_PROJECT_PATH = "/root/cdx/scalelink-frontend"
WEB_HOST_IP = "43.153.21.64"
WEB_HOST_PROJECT_PATH = "/data/webapps/lessie_official_web"
}
stages {
stage('拉取代码') {
steps {
git branch: "${CODE_BRANCH}",
credentialsId: 'fly_gitlab_auth',
url: 'http://172.24.16.20/web/scalelink-frontend.git'
}
}
stage('同步到本地机器') {
steps {
sh """
ssh ${LOCKHOST_IP} 'rm -rf ${LOCKHOST_PROJECT_PATH}/"*"' &&
rsync -az ${WORKSPACE}/ ${LOCKHOST_IP}:${LOCKHOST_PROJECT_PATH}/
"""
}
}
stage('依赖和构建') {
steps {
sh """
ssh ${LOCKHOST_IP} "bash -lc \\"
cd ${LOCKHOST_PROJECT_PATH}/projects/lessie &&
pnpm install --force && pnpm build &&
tar -czf output.tar.gz .output
\\""
"""
}
}
stage('上传产物') {
steps {
sh """
ssh ${LOCKHOST_IP} "bash -lc \\"
scp -r ${LOCKHOST_PROJECT_PATH}/projects/lessie/output.tar.gz 43.153.21.64:${WEB_HOST_PROJECT_PATH}/
\\""
"""
}
}
stage('启动') {
steps {
sh """
ssh ${WEB_HOST_IP} '
cd ${WEB_HOST_PROJECT_PATH} && pm2 list &&
pm2 delete lessie-official-web &&
tar -zxf output.tar.gz &&
pm2 start .output/server/index.mjs --name lessie-official-web --output ./nuxt-out.log --error ./nuxt-error.log
'
"""
}
}
}
}
pipeline {
agent any
environment {
CODE_BRANCH = "dev"
WEB_HOST_IP = "49.51.46.148"
WEB_HOST_PROJECT_PATH = "/data/webapps/lessie_official_web"
}
stages {
stage('checkout 代码') {
steps {
git branch: 'sit', credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/root/fly_moon.git'
}
}
stage('Maven 编译') {
steps {
sh "cd ${WORKSPACE}/ && mvn clean install -P sit -Dmaven.sit.skip=true -pl flymoon-seo -am"
}
}
stage('jar A下线') {
steps {
sh "ssh 192.168.70.18 'sh /data/sh/kill_fly_moon_seo.sh'"
}
}
stage('jar A同步') {
steps {
sh """
scp ${WORKSPACE}/flymoon-seo/target/flymoon-seo.jar 192.168.70.18:/data/webapps/flymoon_seo/
scp ${WORKSPACE}/flymoon-common/target/flymoon-common.jar 192.168.70.18:/data/webapps/flymoon_seo/
scp ${WORKSPACE}/flymoon-framework/target/flymoon-framework.jar 192.168.70.18:/data/webapps/flymoon_seo/
scp ${WORKSPACE}/flymoon-system/target/flymoon-system.jar 192.168.70.18:/data/webapps/flymoon_seo/
"""
}
}
stage('jar A启动') {
steps {
sh "ssh 192.168.70.18 'nohup /data/jdk1.8.0_181/bin/java -jar /data/webapps/flymoon_seo/flymoon-seo.jar --spring.profiles.active=sit >/data/webapps/flymoon_seo/nohup.out 2>&1 &' "
}
}
}
}
# ------------------------7-22备份---------------
pipeline {
agent any
environment {
REMOTE_HOST = "43.130.56.138" // 远程服务器 {params.REMOTE_HOST}
REMOTE_PROJECT_PATH = "/data/webapps/lessie_sourcing_agents" // 远程 Python 项目路径
VENV_DIR = "/data/webapps/lessie_sourcing_agents/venv" // 远程虚拟环境目录
CONDA_PATH = "/root/miniconda3/bin/conda" // 修改为实际 Conda 安装路径
}
stages {
stage('Checkout 代码') {
steps {
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/python/lessie-sourcing-agents.git'
}
}
stage('进程下线') {
steps {
echo("下线")
sh "ssh ${REMOTE_HOST} 'sh /data/sh/kill_lessie_sourcing_agents.sh'"
}
}
stage('工程同步') {
steps {
sh """
ssh ${REMOTE_HOST} 'mkdir -p ${REMOTE_PROJECT_PATH}'
rsync -avz --exclude 'venv' ${WORKSPACE}/ ${REMOTE_HOST}:${REMOTE_PROJECT_PATH}/
"""
}
}
stage('安装依赖') {
steps {
sh """
ssh ${REMOTE_HOST} '
cd ${REMOTE_PROJECT_PATH} &&
source ~/.bashrc &&
conda activate search &&
source ${VENV_DIR}/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt
'
"""
}
}
stage('工程启动') {
steps {
echo("启动")
sh """
ssh ${REMOTE_HOST} '
conda activate search
source ${VENV_DIR}/bin/activate
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
nohup env APP_ENV=sit python /data/webapps/lessie_sourcing_agents/server.py > /data/webapps/lessie_sourcing_agents/logs/lessie_sourcing_agents_\${TIMESTAMP}.log 2>&1 &
'
"""
}
}
}
post {
success {
echo '✅ 部署成功!'
}
failure {
echo '❌ 部署失败,请检查日志!'
}
}
}
# ------------------------7-22备份---------------
# ------------------------7-22 滚动发布实验---------------
pipeline {
agent any
environment {
REMOTE_HOST = "43.130.56.138" // 远程服务器 {params.REMOTE_HOST}
REMOTE_PROJECT_PATH = "/data/webapps/lessie_sourcing_agents" // 远程 Python 项目路径
VENV_DIR = "/data/webapps/lessie_sourcing_agents/venv" // 远程虚拟环境目录
REMOTE_PROJECT_PATH_02 = "/data/webapps/lessie_sourcing_agents_02"
VENV_DIR_02 = "/data/webapps/lessie_sourcing_agents_02/venv"
CONDA_PATH = "/root/miniconda3/bin/conda" // 修改为实际 Conda 安装路径
}
stages {
stage('Checkout 代码') {
steps {
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/python/lessie-sourcing-agents.git'
}
}
stage('进程A下线') {
steps {
echo("下线A")
sh "ssh ${REMOTE_HOST} 'sh /data/sh/kill_lessie_sourcing_agents.sh'"
}
}
stage('工程A同步') {
steps {
sh """
ssh ${REMOTE_HOST} 'mkdir -p ${REMOTE_PROJECT_PATH}'
rsync -avz --exclude 'venv' ${WORKSPACE}/ ${REMOTE_HOST}:${REMOTE_PROJECT_PATH}/
"""
}
}
stage('安装A依赖') {
steps {
sh """
ssh ${REMOTE_HOST} '
cd ${REMOTE_PROJECT_PATH} &&
source ~/.bashrc &&
conda activate search &&
source ${VENV_DIR}/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt
'
"""
}
}
stage('工程A启动') {
steps {
echo("启动A")
sh """
ssh ${REMOTE_HOST} '
conda activate search
source ${VENV_DIR}/bin/activate
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
nohup env APP_ENV=sit python ${REMOTE_PROJECT_PATH}/server.py > ${REMOTE_PROJECT_PATH}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log 2>&1 &
'
"""
}
}
stage('探测A服务 ') {
steps {
echo("探测A服务")
sh "ssh ${REMOTE_HOST} 'sh /data/sh/check_lessie_agents_8000.sh' "
}
}
stage('进程B下线') {
steps {
echo("下线B")
sh "ssh ${REMOTE_HOST} 'sh /data/sh/kill_lessie_sourcing_agents_8002.sh'"
}
}
stage('工程B同步') {
steps {
sh """
ssh ${REMOTE_HOST} 'mkdir -p ${REMOTE_PROJECT_PATH_02}'
rsync -avz --exclude 'venv' ${WORKSPACE}/ ${REMOTE_HOST}:${REMOTE_PROJECT_PATH_02}/
"""
}
}
stage('安装B依赖') {
steps {
sh """
ssh ${REMOTE_HOST} '
cd ${REMOTE_PROJECT_PATH_02} &&
source ~/.bashrc &&
conda activate search &&
source ${VENV_DIR_02}/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt
'
"""
}
}
stage('工程B启动') {
steps {
echo("启动B")
sh """
ssh ${REMOTE_HOST} '
conda activate search
mv ${REMOTE_PROJECT_PATH_02}/server.py ${REMOTE_PROJECT_PATH_02}/server8002.py
source ${VENV_DIR_02}/bin/activate
TIMESTAMP_02=\$(date +"%Y%m%d_%H%M%S")
nohup env APP_ENV=sit python ${REMOTE_PROJECT_PATH_02}/server8002.py --port 8002 > ${REMOTE_PROJECT_PATH_02}/logs/lessie_sourcing_agents_\${TIMESTAMP_02}.log 2>&1 &
'
"""
}
}
}
post {
success {
echo '✅ 部署成功!'
}
failure {
echo '❌ 部署失败,请检查日志!'
}
}
}
# ------------------------7-22 滚动发布实验---------------
# ------------------------7-28 滚动发布 等待连接数为0 再kill ---------------
# 目标服务器脚本
set_s1_backend_weight.sh
wait_s1_for_connections.sh
# ------------------------7-28 滚动发布 等待连接数为0再kill 实验---------------
# ==============9-9双台python==============
pipeline {
agent any
environment {
REMOTE_HOST_A = "43.130.53.202" // 远程服务器A
REMOTE_PROJECT_PATH_A = "/data/webapps/lessie_sourcing_agents" // 远程 Python 项目路径
VENV_DIR_A = "/data/webapps/lessie_sourcing_agents/venv" // 远程虚拟环境目录
CONDA_PATH = "/root/miniconda3/bin/conda" // 修改为实际 Conda 安装路径
}
stages {
stage('Checkout 代码') {
steps {
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/python/lessie-sourcing-agents.git'
}
}
stage('进程A下线') {
steps {
echo("下线A")
sh "ssh ${REMOTE_HOST_A} 'sh /data/sh/kill_lessie_sourcing_agents_8002.sh'"
}
}
stage('工程A同步') {
steps {
echo("同步A")
sh """
ssh ${REMOTE_HOST_A} 'mkdir -p ${REMOTE_PROJECT_PATH_A}'
rsync -avz --exclude 'venv' ${WORKSPACE}/ ${REMOTE_HOST_A}:${REMOTE_PROJECT_PATH_A}/
"""
}
}
stage('安装A依赖') {
steps {
echo("依赖A")
sh """
ssh ${REMOTE_HOST_A} '
cd ${REMOTE_PROJECT_PATH_A} &&
source ~/.bashrc &&
conda activate search &&
source ${VENV_DIR_A}/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt
'
"""
}
}
stage('工程A启动') {
steps {
echo("启动A")
sh """
ssh ${REMOTE_HOST_A} '
conda activate search
source ${VENV_DIR_A}/bin/activate
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
LOGFILE="${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log"
nohup env APP_ENV=s1 python ${REMOTE_PROJECT_PATH_A}/server.py --port 8002 > ${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log 2>&1 &
ln -sf "\$LOGFILE" ${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_latest.log
'
"""
}
}
stage('探测A服务 ') {
steps {
echo("探测A服务")
sh "ssh ${REMOTE_HOST_A} 'sh /data/sh/check_lessie_agents_8002.sh' "
}
}
}
post {
success {
echo '✅ 部署成功!'
}
failure {
echo '❌ 部署失败,请检查日志!'
}
}
}
# ========================9-9双台python==============================
pipeline {
agent any
environment {
REMOTE_HOST_A = "43.130.56.138"
NGINX_HOST_B = "43.130.53.202"
NGINX_HOST = "49.51.46.148"
REMOTE_PROJECT_PATH_A = "/data/webapps/lessie_sourcing_agents"
VENV_DIR_A = "/data/webapps/lessie_sourcing_agents/venv"
REMOTE_PROJECT_PATH_B = "/data/webapps/lessie_sourcing_agents"
VENV_DIR_B = "/data/webapps/lessie_sourcing_agents/venv"
CONDA_PATH = "/root/miniconda3/bin/conda"
NGINX_PY_backend_A = "10.0.0.5"
NGINX_PY_backend_B = "10.0.0.13"
PORT_A = "8000"
PORT_B = "8002"
CONNECTION_TIMEOUT = "600" // 等待连接关闭的超时时间(秒)
NGINX_RELOAD_SCRIPT = "/data/sh/set_s1_backend_weight_new.sh" // 设置nginx后端组up/down
WAIT_CONNECTIONS_SCRIPT = "/data/sh/wait_s1_for_connections.sh" // 等待连接数变为0
CHECK_STATUS_SCRIPT = "/data/sh/check_s1_backend_status.sh" // 检查后端组状态
}
stages {
stage('Checkout 代码') {
steps {
git branch: "${params.Code_branch}", credentialsId: 'fly_gitlab_auth', url: 'http://172.24.16.20/python/lessie-sourcing-agents.git'
}
}
stage('A脱离后端组') {
steps {
echo "将实例A的权重设置为down停止接收新连接"
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_PY_backend_A} ${PORT_A} down'"
echo "等待实例A的现有连接关闭"
sh "ssh ${REMOTE_HOST_A} 'sh ${WAIT_CONNECTIONS_SCRIPT} ${PORT_A} ${CONNECTION_TIMEOUT}'"
}
}
stage('A下线&同步') {
steps {
echo("下线A后同步A")
sh "ssh ${REMOTE_HOST_A} 'sh /data/sh/kill_lessie_sourcing_agents.sh'"
sh """
ssh ${REMOTE_HOST_A} 'mkdir -p ${REMOTE_PROJECT_PATH_A}'
rsync -avz --exclude 'venv' --exclude '.git' ${WORKSPACE}/ ${REMOTE_HOST_A}:${REMOTE_PROJECT_PATH_A}/
"""
}
}
stage('A依赖&启动') {
steps {
echo("A依赖&启动")
sh """
ssh ${REMOTE_HOST_A} '
cd ${REMOTE_PROJECT_PATH_A}
source ~/.bashrc
conda activate search
source ${VENV_DIR_A}/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
LOGFILE="${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log"
nohup env APP_ENV=s1 python ${REMOTE_PROJECT_PATH_A}/server.py --port 8002 > ${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log 2>&1 &
ln -sf "\$LOGFILE" ${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_latest.log
'
"""
}
}
stage('探测A服务 ') {
steps {
echo("探测A服务")
sh "sleep 5"
sh """
ssh ${REMOTE_HOST_A} "head -n 300 ${REMOTE_PROJECT_PATH_A}/logs/lessie_sourcing_agents_latest.log | grep -i 'error' || true"
ssh ${REMOTE_HOST_A} "sh /data/sh/check_lessie_agents_8000.sh"
"""
}
}
stage('恢复A流量') {
steps {
echo "恢复实例A的流量"
sh "sleep 5"
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_PY_backend_A} ${PORT_A} up'"
echo "实例 A 部署完成"
}
}
stage('截B流量') {
steps {
echo "将实例B的权重设置为down停止接收新连接"
sh "ssh ${NGINX_HOST} 'sh ${NGINX_RELOAD_SCRIPT} ${NGINX_PY_backend_B} ${PORT_B} down'"
echo "等待实例B的现有连接关闭"
sh "ssh ${REMOTE_HOST} '${WAIT_CONNECTIONS_SCRIPT} ${PORT_B} ${CONNECTION_TIMEOUT}'"
}
}
stage('B下线&同步') {
steps {
echo("B下线&同步")
sh "ssh ${REMOTE_HOST_B} 'sh /data/sh/kill_lessie_sourcing_agents.sh'"
sh """
ssh ${REMOTE_HOST_B} 'mkdir -p ${REMOTE_PROJECT_PATH_B}'
rsync -avz --exclude 'venv' --exclude '.git' ${WORKSPACE}/ ${REMOTE_HOST_B}:${REMOTE_PROJECT_PATH_B}/
"""
}
}
stage('B依赖&启动') {
steps {
echo("B依赖&启动")
sh """
ssh ${REMOTE_HOST_B} '
cd ${REMOTE_PROJECT_PATH_B} &&
source ~/.bashrc &&
conda activate search &&
source ${VENV_DIR_B}/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
LOGFILE="${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log"
nohup env APP_ENV=s1 python ${REMOTE_PROJECT_PATH_B}/server.py --port 8002 > ${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log 2>&1 &
ln -sf "\$LOGFILE" ${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_latest.log
'
"""
}
}
stage('探测B服务 ') {
steps {
echo("探测B服务")
sh "sleep 5"
sh """
ssh ${REMOTE_HOST_B} "head -n 300 ${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_latest.log | grep -i 'error' || true"
ssh ${REMOTE_HOST_B} "sh /data/sh/check_lessie_agents_8002.sh"
"""
}
}
stage('恢复B流量') {
steps {
echo "恢复实例B的流量"
sh "sleep 5"
sh "ssh ${NGINX_HOST} '${NGINX_RELOAD_SCRIPT_B} ${PORT_B} up'"
echo "实例 B 部署完成"
}
}
}
post {
success {
echo '✅ 部署成功!'
}
failure {
echo '❌ 部署失败,请检查日志!'
}
}
}
#========================================11-19未更改===============================================================================
node {
properties([
parameters([
// 分支选择参数
gitParameter(
branchFilter: 'origin/(.*)',
defaultValue: 'master',
description: 's1环境默认master分支',
name: 'Code_branch',
quickFilterEnabled: true,
selectedValue: 'DEFAULT',
sortMode: 'NONE',
type: 'PT_BRANCH',
size: 1
),
// 部署实例选择
choice(
name: 'DEPLOY_TARGETS',
choices: ['A'],
description: '选择需要部署的实例(多选格式为"A,B"'
),
// 部署顺序
string(
name: 'DEPLOY_ORDER',
defaultValue: 'A',
description: '指定部署顺序如AB、BA必须是已选实例的组合'
)
])
])
// 环境配置(集中管理实例参数)
def config = [
A: [
remoteHost: "43.130.56.138",
projectPath: "/data/webapps/lessie_sourcing_agents",
venvDir: "/data/webapps/lessie_sourcing_agents/.venv",
nginxBackend: "10.0.0.5",
port: "8000",
killScript: "/data/sh/kill_lessie_sourcing_agents.sh",
checkScript: "/data/sh/check_lessie_agents_8000.sh",
gunicornWorkers: 4
],
B: [
remoteHost: "43.130.53.202",
projectPath: "/data/webapps/lessie_sourcing_agents",
venvDir: "/data/webapps/lessie_sourcing_agents/.venv",
nginxBackend: "10.0.0.13",
port: "8002",
killScript: "/data/sh/kill_lessie_sourcing_agents.sh",
checkScript: "/data/sh/check_lessie_agents_8002.sh",
gunicornWorkers: 4
]
]
def commonConfig = [
nginxHost: "49.51.46.148",
connectionTimeout: "600",
nginxReloadScript: "/data/sh/set_s1_backend_weight_new.sh",
waitConnectionsScript: "/data/sh/wait_s1_for_connections.sh"
]
stage('拉代码') {
checkout scm: [
$class: 'GitSCM',
branches: [[name: params.Code_branch]],
userRemoteConfigs: [[
url: 'http://172.24.16.20/python/lessie-sourcing-agents.git',
credentialsId: 'fly_gitlab_auth'
]]
]
}
stage('验证参数') {
def selectedTargets = params.DEPLOY_TARGETS.split(',').toList()
def orderChars = params.DEPLOY_ORDER.split('').toList()
if (orderChars.isEmpty()) {
error("部署顺序不能为空请输入如AB、BA的顺序")
}
orderChars.each { instance ->
if (!selectedTargets.contains(instance)) {
error("部署顺序包含未选择的实例: ${instance},已选实例:${params.DEPLOY_TARGETS}")
}
}
def uniqueOrder = orderChars.unique()
if (uniqueOrder.size() != orderChars.size()) {
error("部署顺序包含重复实例: ${params.DEPLOY_ORDER}")
}
echo "✅ 参数验证通过:已选实例=${selectedTargets},部署顺序=${orderChars}"
env.VALID_ORDER = params.DEPLOY_ORDER
}
stage('动态部署') {
def orderChars = env.VALID_ORDER.split('').toList()
orderChars.each { instance ->
echo "===== 开始部署实例 ${instance} ====="
// 实例部署的5个步骤直接在循环中定义stage无嵌套
stage("${instance}:脱离后端组") {
def cfg = config[instance]
sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxReloadScript} ${cfg.nginxBackend} ${cfg.port} down'"
sh "ssh ${cfg.remoteHost} 'sh ${commonConfig.waitConnectionsScript} ${cfg.port} ${commonConfig.connectionTimeout}'"
}
stage("${instance}下线&同步") {
def cfg = config[instance]
sh "ssh ${cfg.remoteHost} 'sh ${cfg.killScript} ${cfg.port}'"
sh """
ssh ${cfg.remoteHost} 'mkdir -p ${cfg.projectPath}'
rsync -avz --exclude '.venv' --exclude '.git' ${WORKSPACE}/ ${cfg.remoteHost}:${cfg.projectPath}/
"""
}
stage("${instance}依赖&启动") {
def cfg = config[instance]
sh """
ssh ${cfg.remoteHost} '
cd ${cfg.projectPath}
uv sync
source ${cfg.venvDir}/bin/activate
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
LOGFILE="${cfg.projectPath}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log"
nohup env APP_ENV=s1 gunicorn -w ${cfg.gunicornWorkers} -k uvicorn.workers.UvicornWorker \
-b 0.0.0.0:${cfg.port} --timeout 300 dialogue.app:app \
--max-requests 200 --max-requests-jitter 50 \
> "\$LOGFILE" 2>&1 &
ln -sf "\$LOGFILE" ${cfg.projectPath}/logs/lessie_sourcing_agents_latest.log
'
"""
}
stage("探测${instance}探测服务") {
def cfg = config[instance]
sh "sleep 5"
sh "ssh ${cfg.remoteHost} 'head -n 300 ${cfg.projectPath}/logs/lessie_sourcing_agents_latest.log | grep -i error || echo 未发现错误日志'"
sh "ssh ${cfg.remoteHost} 'sh ${cfg.checkScript}'"
}
stage("恢复${instance}流量") {
def cfg = config[instance]
sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxReloadScript} ${cfg.nginxBackend} ${cfg.port} up'"
}
echo "===== 实例 ${instance} 部署完成 ====="
}
}
echo '✅ 所有选中的实例部署成功!'
}
#==================================================11-19未更改====================================================================
#========================================11-19更改===============================================================================
node {
properties([
parameters([
// 分支选择参数
gitParameter(
branchFilter: 'origin/(.*)',
defaultValue: 'master',
description: 's1环境默认master分支',
name: 'Code_branch',
quickFilterEnabled: true,
selectedValue: 'DEFAULT',
sortMode: 'NONE',
type: 'PT_BRANCH',
size: 1
),
// 部署实例选择
choice(
name: 'DEPLOY_TARGETS',
choices: ['A'],
description: '选择需要部署的实例(多选格式为"A,B"'
),
// 部署顺序
string(
name: 'DEPLOY_ORDER',
defaultValue: 'A',
description: '指定部署顺序如AB、BA必须是已选实例的组合'
)
])
])
// 环境配置(集中管理实例参数)
def config = [
A: [
remoteHost: "43.130.56.138",
projectPath: "/data/webapps/lessie_sourcing_agents",
venvDir: "/data/webapps/lessie_sourcing_agents/.venv",
nginxBackend: "10.0.0.5",
port: "8000",
killScript: "/data/sh/kill_lessie_sourcing_agents.sh",
checkScript: "/data/sh/check_lessie_agents_8000.sh",
gunicornWorkers: 4
]
]
def commonConfig = [
nginxHost: "49.51.46.148",
connectionTimeout: "600",
nginxReloadScript: "/data/sh/set_s1_backend_weight_new.sh",
waitConnectionsScript: "/data/sh/wait_s1_for_connections.sh"
]
stage('拉代码') {
checkout scm: [
$class: 'GitSCM',
branches: [[name: params.Code_branch]],
userRemoteConfigs: [[
url: 'http://172.24.16.20/python/lessie-sourcing-agents.git',
credentialsId: 'fly_gitlab_auth'
]]
]
}
stage('验证参数') {
def selectedTargets = params.DEPLOY_TARGETS.split(',').toList()
def orderChars = params.DEPLOY_ORDER.split('').toList()
if (orderChars.isEmpty()) {
error("部署顺序不能为空请输入如AB、BA的顺序")
}
orderChars.each { instance ->
if (!selectedTargets.contains(instance)) {
error("部署顺序包含未选择的实例: ${instance},已选实例:${params.DEPLOY_TARGETS}")
}
}
def uniqueOrder = orderChars.unique()
if (uniqueOrder.size() != orderChars.size()) {
error("部署顺序包含重复实例: ${params.DEPLOY_ORDER}")
}
echo "✅ 参数验证通过:已选实例=${selectedTargets},部署顺序=${orderChars}"
env.VALID_ORDER = params.DEPLOY_ORDER
}
stage('动态部署') {
def orderChars = env.VALID_ORDER.split('').toList()
orderChars.each { instance ->
echo "===== 开始部署实例 ${instance} ====="
// 实例部署的5个步骤直接在循环中定义stage无嵌套
stage("${instance}:脱离后端组") {
def cfg = config[instance]
sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxReloadScript} ${cfg.nginxBackend} ${cfg.port} down'"
sh "ssh ${cfg.remoteHost} 'sh ${commonConfig.waitConnectionsScript} ${cfg.port} ${commonConfig.connectionTimeout}'"
}
stage("${instance}下线&同步") {
def cfg = config[instance]
sh "ssh ${cfg.remoteHost} 'sh ${cfg.killScript} ${cfg.port}'"
sh """
ssh ${cfg.remoteHost} 'mkdir -p ${cfg.projectPath}'
rsync -avz --exclude '.venv' --exclude '.git' ${WORKSPACE}/ ${cfg.remoteHost}:${cfg.projectPath}/
"""
}
stage("${instance}依赖&启动") {
def cfg = config[instance]
sh """
ssh ${cfg.remoteHost} '
cd ${cfg.projectPath}
uv sync
source ${cfg.venvDir}/bin/activate
TIMESTAMP=\$(date +"%Y%m%d_%H%M%S")
LOGFILE="${cfg.projectPath}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log"
nohup env APP_ENV=s1 gunicorn -w ${cfg.gunicornWorkers} -k uvicorn.workers.UvicornWorker \
-b 0.0.0.0:${cfg.port} --timeout 300 dialogue.app:app \
--max-requests 200 --max-requests-jitter 50 \
> "\$LOGFILE" 2>&1 &
ln -sf "\$LOGFILE" ${cfg.projectPath}/logs/lessie_sourcing_agents_latest.log
'
"""
}
stage("探测${instance}探测服务") {
def cfg = config[instance]
sh "sleep 5"
sh "ssh ${cfg.remoteHost} 'head -n 300 ${cfg.projectPath}/logs/lessie_sourcing_agents_latest.log | grep -i error || echo 未发现错误日志'"
sh "ssh ${cfg.remoteHost} 'sh ${cfg.checkScript}'"
}
stage("恢复${instance}流量") {
def cfg = config[instance]
sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxReloadScript} ${cfg.nginxBackend} ${cfg.port} up'"
}
echo "===== 实例 ${instance} 部署完成 ====="
}
}
echo '✅ 所有选中的实例部署成功!'
stage("POST") {
// python 环境
env.PY_environment = 's1'
// git 提交短哈希
env.GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
// git 作者
env.GIT_AUTHOR = sh(script: 'git log -1 --pretty=format:%an', returnStdout: true).trim()
// git 提交信息
env.GIT_COMMIT_MSG = sh(script: 'git log -1 --pretty=format:%B', returnStdout: true).trim()
// 拼接荷载信息
def payload = [
env: env.PY_environment,
usage_desc: [
code_branch : params.Code_branch,
git_commit_short : env.GIT_COMMIT_SHORT,
git_author : env.GIT_AUTHOR,
git_commit_msg : env.GIT_COMMIT_MSG
]
]
// JSON —— 转义所有字符
def jsonStr = groovy.json.JsonOutput.toJson(payload)
// 请求 apex URL
def URL = "http://43.159.145.241:8200/api/public/env-usage/env-usage"
echo "正在发送请求到 ${URL}"
echo "JSON Payload: ${jsonStr}"
sh """
curl -X POST "${URL}" \
-H "Content-Type: application/json" \
-d '${jsonStr}'
"""
echo "请求完成"
}
}
#==================================================11-19更改====================================================================