From 7500be151144a051cf0a551ac14c70e74fa26cf7 Mon Sep 17 00:00:00 2001 From: dxin Date: Thu, 18 Dec 2025 15:22:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E7=BA=BF=E4=B8=8A=E6=B5=81?= =?UTF-8?q?=E6=B0=B4=E7=BA=BF=E4=B8=BAuv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jenkins/流水线配置/app_lessie_ai/原.conf | 346 +++++++++++++++++++ jenkins/流水线配置/app_lessie_ai/原改uv.conf | 203 +++++++++++ 2 files changed, 549 insertions(+) create mode 100644 jenkins/流水线配置/app_lessie_ai/原.conf create mode 100644 jenkins/流水线配置/app_lessie_ai/原改uv.conf diff --git a/jenkins/流水线配置/app_lessie_ai/原.conf b/jenkins/流水线配置/app_lessie_ai/原.conf new file mode 100644 index 0000000..d7b0328 --- /dev/null +++ b/jenkins/流水线配置/app_lessie_ai/原.conf @@ -0,0 +1,346 @@ +node { + properties([ + parameters([ + // 分支选择参数 + gitParameter( + branchFilter: 'origin/(.*)', + defaultValue: 'master', + description: 'prod环境,默认master分支', + name: 'Code_branch', + quickFilterEnabled: true, + selectedValue: 'DEFAULT', + sortMode: 'NONE', + type: 'PT_BRANCH' + ), + // 选择部署实例 + extendedChoice( + name: 'DEPLOY_TARGETS', + type: 'PT_CHECKBOX', + description: "选择需要部署的实例(可勾选多个)\n" + + " A:prod-lessie-server01(43.130.59.68)\n" + + " B:prod-lessie-server02(43.173.126.43)\n" + + " C:prod-lessie-server03(49.51.189.136)\n" + + " D:prod-lessie-server04(170.106.187.156)\n" + + " E:prod-lessie-server05(43.130.53.202)", + value: 'A,B,C,D,E', + defaultValue: 'A,B,C,D,E', + visibleItemCount: 5, + delimiter: ',' + ), + // 部署顺序 + string( + name: 'DEPLOY_ORDER', + defaultValue: 'ABCDE', + description: '指定部署顺序(格式:无分隔符,如勾选A、B则填AB或BA;勾选B、C则填BC或CB)' + ) + ]) + ]) + + + // 环境配置(集中管理实例参数) + def config = [ + A: [ + remoteHost: "43.130.59.68", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/venv", + nginxBackend: "10.0.0.12", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 4 + ], + B: [ + remoteHost: "43.173.126.43", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/venv", + nginxBackend: "10.0.0.7", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 4 + ], + C: [ + remoteHost: "49.51.189.136", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/venv", + nginxBackend: "10.0.0.11", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 4 + ], + D: [ + remoteHost: "170.106.187.156", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/venv", + nginxBackend: "10.0.0.2", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 8 + ], + E: [ + remoteHost: "43.130.53.202", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/venv", + nginxBackend: "10.0.0.13", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 8 + ] + ] + + def commonConfig = [ + nginxHost: "49.51.46.148", + connectionTimeout: "3600", + nginxReloadScript: "/data/sh/set_prod_py_backend_weight.sh", + nginxgotopyScript:"/data/sh/set_go_to_py_backend_weight.sh", + waitConnectionsScript: "/data/sh/wait_prod_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(',').collect { it.trim() }.toList() + def orderChars = params.DEPLOY_ORDER.trim().split('').toList() + + if (selectedTargets.isEmpty() || selectedTargets == ['']) { + error("请至少勾选1个需要部署的实例(A/B/C)") + } + + if (orderChars.isEmpty()) { + error("部署顺序不能为空,请按勾选实例输入顺序(如勾选B、C则填BC或CB)") + } + + orderChars.each { instance -> + if (!selectedTargets.contains(instance)) { + error("部署顺序【${params.DEPLOY_ORDER}】包含未勾选的实例【${instance}】,已勾选实例:${params.DEPLOY_TARGETS}") + } + } + + if (orderChars.unique().size() != orderChars.size()) { + error("部署顺序【${params.DEPLOY_ORDER}】包含重复实例(如AAB),请输入无重复顺序") + } + + if (orderChars.size() != selectedTargets.size()) { + error("部署顺序【${params.DEPLOY_ORDER}】有${orderChars.size()}个实例,已勾选实例有${selectedTargets.size()}个,数量需一致") + } + echo "参数验证通过:已选实例=${selectedTargets},部署顺序:${orderChars}" + env.VALID_ORDER = params.DEPLOY_ORDER + } + + stage('动态部署') { + def orderChars = env.VALID_ORDER.split('').toList() + orderChars.each { instance -> + echo "===== 开始部署实例 ${instance} =====" + + // 实例部署的5个步骤 + stage("${instance}脱离后端组") { + def cfg = config[instance] + sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxReloadScript} ${cfg.nginxBackend} ${cfg.port} down'" + sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxgotopyScript} ${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} + source ~/.bashrc + conda activate search + source ${cfg.venvDir}/bin/activate + pip install --upgrade pip + pip install -r requirements.txt + which python + TIMESTAMP=\$(date +"%Y%m%d_%H%M%S") + LOGFILE="${cfg.projectPath}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log" + nohup env APP_ENV=prod gunicorn -w ${cfg.gunicornWorkers} -k uvicorn.workers.UvicornWorker \ + -b 0.0.0.0:${cfg.port} --timeout 300 dialogue.app:app \ + --max-requests 300 --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'" + sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxgotopyScript} ${cfg.nginxBackend} ${cfg.port} up'" + } + + echo "===== 实例 ${instance} 部署完成 =====" + } + } + + echo '✅ 所有选中的实例部署成功!' +} + + + + + + + + + +// pipeline { +// agent any + +// environment { +// REMOTE_HOST_A = "43.130.56.138" // 远程服务器A +// REMOTE_HOST_B = "43.130.59.68" // 远程服务器B + +// REMOTE_PROJECT_PATH_A = "/data/webapps/prod_lessie_sourcing_agents" // 远程 Python 项目路径 +// VENV_DIR_A = "/data/webapps/prod_lessie_sourcing_agents/venv" // 远程虚拟环境目录 + +// REMOTE_PROJECT_PATH_B = "/data/webapps/prod_lessie_sourcing_agents" +// VENV_DIR_B = "/data/webapps/prod_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_7001.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 +// mv ${REMOTE_PROJECT_PATH_A}/server.py ${REMOTE_PROJECT_PATH_A}/server7001.py +// 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=prod python ${REMOTE_PROJECT_PATH_A}/server7001.py --port 7001 > ${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_7001.sh' " +// } +// } + +// stage('进程B下线') { +// steps { +// echo("下线B") +// sh "ssh ${REMOTE_HOST_B} 'sh /data/sh/kill_lessie_sourcing_agents_7001.sh'" +// } +// } +// stage('工程B同步') { +// steps { +// echo("同步B") +// sh """ +// ssh ${REMOTE_HOST_B} 'mkdir -p ${REMOTE_PROJECT_PATH_B}' +// rsync -avz --exclude 'venv' ${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 +// ' +// """ +// } +// } +// stage('工程B启动') { +// steps { +// echo("启动B") +// sh """ +// ssh ${REMOTE_HOST_B} ' +// conda activate search +// mv ${REMOTE_PROJECT_PATH_B}/server.py ${REMOTE_PROJECT_PATH_B}/server7001.py +// source ${VENV_DIR_B}/bin/activate +// TIMESTAMP_02=\$(date +"%Y%m%d_%H%M%S") +// LOGFILE="${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_\${TIMESTAMP_02}.log" +// nohup env APP_ENV=prod python ${REMOTE_PROJECT_PATH_B}/server7001.py --port 7001 > ${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_\${TIMESTAMP_02}.log 2>&1 & +// ln -sf "\$LOGFILE" ${REMOTE_PROJECT_PATH_B}/logs/lessie_sourcing_agents_latest.log +// ' +// """ +// } +// } +// } + + +// post { +// success { +// echo '✅ 部署成功!' +// } +// failure { +// echo '❌ 部署失败,请检查日志!' +// } +// } +// } diff --git a/jenkins/流水线配置/app_lessie_ai/原改uv.conf b/jenkins/流水线配置/app_lessie_ai/原改uv.conf new file mode 100644 index 0000000..088bf6d --- /dev/null +++ b/jenkins/流水线配置/app_lessie_ai/原改uv.conf @@ -0,0 +1,203 @@ +node { + properties([ + parameters([ + // 分支选择参数 + gitParameter( + branchFilter: 'origin/(.*)', + defaultValue: 'master', + description: 'prod环境,默认master分支', + name: 'Code_branch', + quickFilterEnabled: true, + selectedValue: 'DEFAULT', + sortMode: 'NONE', + type: 'PT_BRANCH' + ), + // 选择部署实例 + extendedChoice( + name: 'DEPLOY_TARGETS', + type: 'PT_CHECKBOX', + description: "选择需要部署的实例(可勾选多个)\n" + + " A:prod-lessie-server01(43.130.59.68)\n" + + " B:prod-lessie-server02(43.173.126.43)\n" + + " C:prod-lessie-server03(49.51.189.136)\n" + + " D:prod-lessie-server04(170.106.187.156)\n" + + " E:prod-lessie-server05(43.130.53.202)", + value: 'A,B,C,D,E', + defaultValue: 'A,B,C,D,E', + visibleItemCount: 5, + delimiter: ',' + ), + // 部署顺序 + string( + name: 'DEPLOY_ORDER', + defaultValue: 'ABCDE', + description: '指定部署顺序(格式:无分隔符,如勾选A、B则填AB或BA;勾选B、C则填BC或CB)' + ) + ]) + ]) + + + // 环境配置(集中管理实例参数) + def config = [ + A: [ + remoteHost: "43.130.59.68", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/.venv", + nginxBackend: "10.0.0.12", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 4 + ], + B: [ + remoteHost: "43.173.126.43", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/.venv", + nginxBackend: "10.0.0.7", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 4 + ], + C: [ + remoteHost: "49.51.189.136", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/.venv", + nginxBackend: "10.0.0.11", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 4 + ], + D: [ + remoteHost: "170.106.187.156", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/.venv", + nginxBackend: "10.0.0.2", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 8 + ], + E: [ + remoteHost: "43.130.53.202", + projectPath: "/data/webapps/prod_lessie_sourcing_agents", + venvDir: "/data/webapps/prod_lessie_sourcing_agents/.venv", + nginxBackend: "10.0.0.13", + port: "7001", + killScript: "/data/sh/kill_lessie_sourcing_agents.sh", + checkScript: "/data/sh/check_lessie_agents_7001.sh", + gunicornWorkers: 8 + ] + ] + + def commonConfig = [ + nginxHost: "49.51.46.148", + connectionTimeout: "3600", + nginxReloadScript: "/data/sh/set_prod_py_backend_weight.sh", + nginxgotopyScript:"/data/sh/set_go_to_py_backend_weight.sh", + waitConnectionsScript: "/data/sh/wait_prod_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(',').collect { it.trim() }.toList() + def orderChars = params.DEPLOY_ORDER.trim().split('').toList() + + if (selectedTargets.isEmpty() || selectedTargets == ['']) { + error("请至少勾选1个需要部署的实例(A/B/C)") + } + + if (orderChars.isEmpty()) { + error("部署顺序不能为空,请按勾选实例输入顺序(如勾选B、C则填BC或CB)") + } + + orderChars.each { instance -> + if (!selectedTargets.contains(instance)) { + error("部署顺序【${params.DEPLOY_ORDER}】包含未勾选的实例【${instance}】,已勾选实例:${params.DEPLOY_TARGETS}") + } + } + + if (orderChars.unique().size() != orderChars.size()) { + error("部署顺序【${params.DEPLOY_ORDER}】包含重复实例(如AAB),请输入无重复顺序") + } + + if (orderChars.size() != selectedTargets.size()) { + error("部署顺序【${params.DEPLOY_ORDER}】有${orderChars.size()}个实例,已勾选实例有${selectedTargets.size()}个,数量需一致") + } + echo "参数验证通过:已选实例=${selectedTargets},部署顺序:${orderChars}" + env.VALID_ORDER = params.DEPLOY_ORDER + } + + stage('动态部署') { + def orderChars = env.VALID_ORDER.split('').toList() + orderChars.each { instance -> + echo "===== 开始部署实例 ${instance} =====" + + // 实例部署的5个步骤 + stage("${instance}脱离后端组") { + def cfg = config[instance] + sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxReloadScript} ${cfg.nginxBackend} ${cfg.port} down'" + sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxgotopyScript} ${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 '.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 + which python + TIMESTAMP=\$(date +"%Y%m%d_%H%M%S") + LOGFILE="${cfg.projectPath}/logs/lessie_sourcing_agents_\${TIMESTAMP}.log" + nohup env APP_ENV=prod gunicorn -w ${cfg.gunicornWorkers} -k uvicorn.workers.UvicornWorker \ + -b 0.0.0.0:${cfg.port} --timeout 300 dialogue.app:app \ + --max-requests 300 --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'" + sh "ssh ${commonConfig.nginxHost} 'sh ${commonConfig.nginxgotopyScript} ${cfg.nginxBackend} ${cfg.port} up'" + } + + echo "===== 实例 ${instance} 部署完成 =====" + } + } + + echo '✅ 所有选中的实例部署成功!' +} + +