智能
助手
最大化  清空记录 停止  历史记录
翻译选中文本
选中一段文本后进行翻译
名词解释
选中一段文本后进行名词解释
知识图谱生成
通过图谱展示知识信息
登录用户在知识浏览页面可用
答案生成
AI自动回答一个问答功能中的问题
登录用户在问答浏览页面,且问题开放回答中可用
知识摘要
自动为当前知识生成摘要
知识浏览页面可用
知识问答
针对当前知识进行智能问答
知识浏览面可用
2025-11-24 16:20:21 版本 : 7.9 创建maven项目-02-使用Pipeline部署maven项目
作者: 文艺范儿 于 2025年11月24日 发布在分类 / DevOps / maven 下,并于 2025年11月24日 编辑
 历史版本

备注 修改日期 修改人
创建版本 2025-11-24 16:20:21[当前版本] 文艺范儿

7.9 创建maven项目

5.使用Pipeline部署maven项目

##先在gitlab上面创建hello-world-war项目,并上传代码,并且要jenkins服务器要有权限git clone代码,此处不做描述。

a. 新建任务

点击 "新建任务"

输入任务名称pipeline_deploy_hello_world,选择 "Pipeline"

点击 "确定"

b. 配置mvn的环境变量

粘贴图片


c.编写shell脚本

#!/bin/bash
# /home/deploy/scripts/pipeline_deploy_hello_world.sh - 简化优化版

set -e  # 遇到错误立即退出

# 配置参数 - 使用环境变量默认值
CODE_DIR=${CODE_DIR:-"${WORKSPACE}"}
DEPLOY_DIR="/home/deploy/tomcat-8-8080/webapps/"
TARGET_IP=${TARGET_IP:-"10.0.0.204"}
TOMCAT_PORT=${TOMCAT_PORT:-"8080"}
PROJECT_NAME="hello-world-war"

# 设置默认值
ACTION=${ACTION:-"deploy"}
GIT_TAG=${GIT_TAG:-"v1.0.1"}

# 颜色输出函数
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

echo "=== 部署脚本开始执行 ==="
echo "动作: $ACTION"
echo "版本: $GIT_TAG"
echo "目标服务器: $TARGET_IP"
echo "代码目录: $CODE_DIR"

# 参数验证
validate_params() {
    if [[ -z "$GIT_TAG" ]]; then
        log_error "GIT_TAG 参数不能为空"
        exit 1
    fi
    
    if [[ -z "$TARGET_IP" ]]; then
        log_error "TARGET_IP 参数不能为空"
        exit 1
    fi
    
    if [[ ! -d "$CODE_DIR" ]]; then
        log_error "代码目录不存在: $CODE_DIR"
        exit 1
    fi
}

# 检查服务器连通性
check_connectivity() {
    log_info "检查服务器连通性..."
    if ! ssh $TARGET_IP "echo '✅ 服务器连接成功'"; then
        log_error "无法连接到服务器: $TARGET_IP"
        exit 1
    fi
}

# 获取Git信息
get_git_info() {
    log_info "获取Git版本信息..."
    if [ -d "$CODE_DIR/.git" ]; then
        cd "$CODE_DIR"
        GIT_COMMIT=$(git rev-parse --short HEAD)
        
        # 兼容旧版Git获取分支名
        if git rev-parse --abbrev-ref HEAD >/dev/null 2>&1; then
            GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
        else
            GIT_BRANCH=$(git branch | grep '^\*' | cut -d' ' -f2)
        fi
        
        GIT_TAG_CURRENT=$(git describe --tags --always 2>/dev/null || echo "无标签")
        
        log_info "Git信息 - 提交: $GIT_COMMIT, 分支: $GIT_BRANCH, 标签: $GIT_TAG_CURRENT"
    else
        log_warn "非Git仓库,跳过Git信息获取"
    fi
}

# Maven构建
get_code_mvn(){
    log_info "Maven构建: $PROJECT_NAME-${GIT_TAG}"
    
    cd "$CODE_DIR"
    
    # 显示项目信息
    log_info "当前工作目录: $(pwd)"
    
    # 检查pom.xml文件
    if [ ! -f "pom.xml" ]; then
        log_error "未找到pom.xml文件"
        exit 1
    fi
    
    # 执行Maven构建
    log_info "开始Maven构建..."
    mvn clean compile package -DskipTests -U
    
    if [ $? -ne 0 ]; then
        log_error "Maven构建失败"
        exit 1
    fi
    
    # 验证构建产物
    WAR_FILE=$(find target/ -name "*.war" 2>/dev/null | head -1)
    if [ -z "$WAR_FILE" ]; then
        log_error "未找到WAR文件"
        exit 1
    fi
    
    log_info "✅ 构建成功: $WAR_FILE"
}

# 传输WAR文件
scp_code_hello-world-war(){
    log_info "传输WAR文件到服务器..."
    
    WAR_FILE=$(find "$CODE_DIR"/target/ -name "*.war" 2>/dev/null | head -1)
    if [ -z "$WAR_FILE" ]; then
        log_error "未找到WAR文件"
        exit 1
    fi
    
    WAR_FILE_NAME=$(basename "$WAR_FILE")
    log_info "传输文件: $WAR_FILE -> $TARGET_IP:/opt/$PROJECT_NAME-${GIT_TAG}/"
    
    ssh $TARGET_IP "mkdir -p /opt/$PROJECT_NAME-${GIT_TAG}"
    scp "$WAR_FILE" "$TARGET_IP:/opt/$PROJECT_NAME-${GIT_TAG}/"
    
    log_info "✅ 文件传输完成"
}

# 解压WAR文件
code_unzip(){
    log_info "解压WAR文件..."
    
    WAR_FILE_NAME=$(find "$CODE_DIR"/target/ -name "*.war" 2>/dev/null | head -1 | xargs basename 2>/dev/null)
    if [ -z "$WAR_FILE_NAME" ]; then
        log_error "无法确定WAR文件名"
        exit 1
    fi
    
    ssh $TARGET_IP "
        mkdir -p /opt/$PROJECT_NAME-${GIT_TAG}/ROOT/
        cd /opt/$PROJECT_NAME-${GIT_TAG}/
        if [ -f \"$WAR_FILE_NAME\" ]; then
            unzip -q -o \"$WAR_FILE_NAME\" -d ROOT/
            echo \"✅ 解压完成\"
        else
            echo \"❌ WAR文件不存在: $WAR_FILE_NAME\"
            exit 1
        fi
    "
}

# 创建软链接
ln_root(){
    log_info "创建软链接..."
    
    ssh $TARGET_IP "
        cd $DEPLOY_DIR
        # 备份现有ROOT目录
        if [ -L \"ROOT\" ]; then
            CURRENT_LINK=\$(readlink ROOT)
            echo \"当前软链接指向: \$CURRENT_LINK\"
        elif [ -d \"ROOT\" ]; then
            echo \"备份现有ROOT目录\"
            tar -czf /tmp/ROOT-backup-\$(date +%Y%m%d-%H%M%S).tar.gz ROOT/ 2>/dev/null || echo \"备份失败,继续执行\"
        fi
        
        # 创建新软链接
        rm -rf ROOT
        ln -sf /opt/$PROJECT_NAME-${GIT_TAG}/ROOT ROOT
        echo \"✅ 软链接创建完成: ROOT -> /opt/$PROJECT_NAME-${GIT_TAG}/ROOT\"
    "
}

# 重启Tomcat
restart_tomcat(){
    log_info "重启Tomcat服务..."
    
    ssh $TARGET_IP "
        echo \"停止Tomcat...\"
        /etc/init.d/tomcat_${TOMCAT_PORT} stop || echo \"停止Tomcat失败,可能未运行\"
        sleep 5
        
        # 检查是否还有Tomcat进程
        if ps aux | grep tomcat | grep ${TOMCAT_PORT} | grep -v grep > /dev/null; then
            echo \"强制杀死Tomcat进程...\"
            pkill -9 -f tomcat.*${TOMCAT_PORT}
            sleep 2
        fi
        
        echo \"启动Tomcat...\"
        /etc/init.d/tomcat_${TOMCAT_PORT} start
        echo \"✅ Tomcat重启完成\"
    "
    
    sleep 10
}

# 健康检查
health_check(){
    log_info "执行健康检查..."
    max_attempts=30
    attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if ssh $TARGET_IP "curl -f -s --connect-timeout 5 http://localhost:$TOMCAT_PORT/ > /dev/null 2>&1"; then
            log_info "✅ 应用健康检查通过 (尝试 $attempt/$max_attempts)"
            return 0
        fi
        log_info "尝试 $attempt/$max_attempts: 应用尚未就绪,等待5秒..."
        sleep 5
        attempt=$((attempt + 1))
    done
    
    log_error "❌ 应用健康检查失败"
    return 1
}

# 部署主流程
main(){
    validate_params
    check_connectivity
    get_git_info
    get_code_mvn
    scp_code_hello-world-war
    code_unzip
    ln_root
    restart_tomcat
    health_check
}

# 回滚流程
rollback(){
    validate_params
    check_connectivity
    ln_root
    restart_tomcat
    health_check
}

# 主执行逻辑
case "$ACTION" in
    "deploy")
        main
        ;;
    "rollback")
        rollback
        ;;
    *)
        log_error "错误: 未知的操作类型: $ACTION"
        echo "用法: ACTION=deploy|rollback GIT_TAG=版本号 TARGET_IP=目标IP $0"
        exit 1
        ;;
esac

log_info "=== 部署脚本执行完成 ==="


d.配置Pipeline

pipeline {
    agent any
    
    parameters {
        choice(
            name: 'ACTION',
            choices: ['deploy', 'rollback'],
            description: '选择部署或回滚操作'
        )
        
        gitParameter(
            name: 'GIT_TAG',
            type: 'PT_TAG',
            description: '选择Git标签版本',
            defaultValue: 'v1.0.1',
            sortMode: 'DESCENDING_SMART'
        )
    }
    
    environment {
        M2_HOME = '/home/deploy/maven'
        PATH = "$M2_HOME/bin:$PATH"
        PROJECT_NAME = 'hello-world-war'
        GIT_REPO = 'git@10.0.0.200:ops/hello-world-war.git'
        TARGET_IP = '10.0.0.204'
        TOMCAT_PORT = '8080'
    }
    
    stages {
        stage('初始化') {
            steps {
                script {
                    echo "=== 流水线开始执行 ==="
                    echo "操作类型: ${params.ACTION}"
                    echo "Git标签: ${params.GIT_TAG}"
                    echo "目标服务器: ${env.TARGET_IP}"
                    
                    // 验证参数
                    if (!params.GIT_TAG) {
                        error("GIT_TAG参数不能为空")
                    }
                    
                    // 设置环境变量
                    env.ACTION = params.ACTION
                    env.GIT_TAG = params.GIT_TAG
                    env.CODE_DIR = "${WORKSPACE}"
                }
            }
        }
        
        stage('检出代码') {
            steps {
                script {
                    echo "检出指定标签代码: ${params.GIT_TAG}"
                    
                    checkout([
                        $class: 'GitSCM',
                        branches: [[name: "refs/tags/${params.GIT_TAG}"]],
                        userRemoteConfigs: [[
                            url: "${env.GIT_REPO}",
                            credentialsId: 'git-ssh-key'
                        ]],
                        extensions: [
                            [$class: 'CloneOption', depth: 1, noTags: false, shallow: true],
                            [$class: 'CleanCheckout']
                        ]
                    ])
                    
                    // 获取Git信息并直接设置环境变量
                    sh '''
                        echo "=== Git信息 ==="
                        git log -1 --oneline
                        GIT_COMMIT_SHORT=$(git rev-parse --short HEAD)
                        echo "Git提交: $GIT_COMMIT_SHORT"
                        echo "Git标签: ${GIT_TAG}"
                    '''
                }
            }
        }
        
        stage('执行部署/回滚') {
            steps {
                script {
                    echo "执行${params.ACTION}操作 - 版本: ${params.GIT_TAG}"
                    
                    sh '''
                        echo "使用部署脚本: /home/deploy/scripts/pipeline_deploy_hello_world.sh"
                        if [ -f "/home/deploy/scripts/pipeline_deploy_hello_world.sh" ]; then
                            chmod +x /home/deploy/scripts/pipeline_deploy_hello_world.sh
                            /home/deploy/scripts/pipeline_deploy_hello_world.sh
                        else
                            echo "错误: 部署脚本不存在"
                            exit 1
                        fi
                    '''
                }
            }
        }
    }
    
    post {
        always {
            script {
                echo "=== 流水线执行完成 ==="
                echo "操作类型: ${params.ACTION}"
                echo "版本: ${params.GIT_TAG}"
                echo "状态: ${currentBuild.result ?: 'SUCCESS'}"
            }
        }
        
        success {
            echo "✅ 操作成功完成"
        }
        
        failure {
            echo "❌ 操作失败"
        }
    }
}

d.保存并构建测试

粘贴图片

粘贴图片

粘贴图片


历史版本-目录  [回到顶端]
    文艺知识分享平台 -V 5.2.5 -wcp