diff --git a/jenkins/流水线配置/s1_jennie_im.conf b/jenkins/流水线配置/s1.jennie.im.conf similarity index 59% rename from jenkins/流水线配置/s1_jennie_im.conf rename to jenkins/流水线配置/s1.jennie.im.conf index 4b47924..38adf09 100644 --- a/jenkins/流水线配置/s1_jennie_im.conf +++ b/jenkins/流水线配置/s1.jennie.im.conf @@ -597,4 +597,345 @@ pipeline { echo '❌ 部署失败,请检查日志!' } } -} \ No newline at end of file +} + + +#========================================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更改==================================================================== + +