美文网首页
Jenkins 持续集成工具 实践中的那些事

Jenkins 持续集成工具 实践中的那些事

作者: 33d31a1032df | 来源:发表于2017-06-15 17:23 被阅读289次

    Jenkins是基于Java开发的一种持续集成工具,是一个开放易用的软件平台。

    • 持续的软件版本发布/测试项目。
    • 监控外部调用执行的工作。

    安装

    Jenkins有多种安装方式,包括Linux、Max OS、Window等,这里我只介绍最简单的方式,使用war包,通过java启动。

    下载地址:https://jenkins.io/download

    java -jar jenkins.war --httpPort=8081
    
    • httpPort 用于指定启动的端口号,如果不加此参数,默认为8080

    启动后,就可以通过http://localhost:8081访问了

    从提示的路径/root/.jenkins/secrets/initialAdminPassword中获取解决密码

    jenkins-unlock

    选择Select plugins to install,自己根据需求选择要安装的插件

    jenkins-customize

    点击上面的【None】,不选择任何插件

    jenkins-customize-plugins

    创建管理用户

    jenkins-create-user

    Jenkins首页

    jenkins-home

    基础配置

    依次进入【系统管理】 -> 【Global Tool Configuration】

    分别新增【JDK】、【Maven】,并保存

    jenkins-global-tool-configuration

    安装插件

    依次进入【系统管理】 -> 【插件管理】 -> 【可选插件】

    可以直接通过Ctrl + F在浏览器上搜索,快速找出指定插件

    • Folders Plugin 创建任务分组,方便管理
    • Git plugin 从Git中获取源码
    • Publish Over SSH 把本地文件发布到远程,还可以发送一些命令到远程机器上执行
    • Multiple SCMs Plugin 一个项目中同时多不同的Git源获取代码

    坑:安装过程中如果有失败的,可以把失败的插件记下来,回到【可选插件】重新安装,或者【已安装】中卸载后重新安装。如果还不行,或者有莫名其妙的错误提示,可以重启Jenkins服务试试

    系统设置

    依次进入【系统管理】 -> 【系统设置】

    设置Publish Over SSH插件的远程机器的连接账号

    翻到【Publish over SSH】新增【SSH Servers】,可以点【Test Configuration】测试连接是否成功

    jenkins-publish-over-ssh-configuration

    坑:无法保存【Remote Directory】、【Passphrase / Password】,导致之后的使用过程中无法正常连接。最后我是使用浏览器的【无痕】模式打开页面,才保存成功了

    创建任务

    依次进入【新建】,名称spring-boot-example,类型Floder

    jenkins-new-job

    点击【New Item】,名称deploy,类型构建一个自由风格的软件项目

    jenkins-job-new-item

    选择【构建】页,添加两个【Execute shell】,添加两个【Send files or execute commands over SSH】

    不使用【源码管理】页中的Git,使用本地Git,编译后再复制到Job工作目录下,这样可以更灵活的处理源码

    spring-boot-example 示例:GitHub

    坑:Jenkins的【源码管理】每次更新代码的时候,都会把已有的修改重置,但是我需要对源码做特殊的修改,就选择了这么处理

    # 1. 更新Git
    # 2. 编码源码
    cd /usr/conanli-repository/spring-boot-example && git pull
    mvn -f /root/conanli-repository/spring-boot-example/spring-boot-example-admin-server clean install -Dmaven.test.skip=true
    
    # 1. 清空Job工作目录
    # 2. 把自己封装的脚本,以及打包后的jar包复制到Job工作目录下
    rm -f $WORKSPACE/*
    cp -f /root/conanli-repository/conan.sh $WORKSPACE
    cp -f /root/conanli-repository/spring-boot-example/spring-boot-example-admin-server/target/spring-boot-example-admin-server-*.jar $WORKSPACE
    

    选择我们刚新增的SSH Server 192.168.198.161

    把脚本conan.sh(文章未附具体内容)上传到/conanli-workspace,并执行

    坑:上传的远程目录Remote directory是相对目录,相对于我们新建SSH Server时的/root目录,所以文件最后会上传到/root/conanli-workspace

    坑:上传的脚本是不可执行的,需要使用sh conan.sh的形式执行

    坑:脚本内没有引入自定义的PATH环境,例如我的JDK是解压安装的,在脚本内有使用java命令,那么我需要在脚本中添加export PATH=$PATH:/usr/jdk8/bin

    # 对旧的jar包进行备份,关闭,删除
    cd /root/conanli-workspace
    sh conan.sh -f spring-boot-example-admin-server-*.jar -D backup backup stop remove
    

    把jar包spring-boot-example-admin-server-*.jar上传到/conanli-workspace,并执行

    # 启动新的jar包
    cd /root/conanli-workspace
    sh conan.sh -f spring-boot-example-admin-server-*.jar -l spring-boot-example-admin-server.log start
    
    jenkins-job-deploy

    执行任务

    保存编辑,点击【立即构建】

    在【Build History】中选择相应的记录,在【Console Output】可以看到部分执行记录

    jenkins-execute-job jenkins-build-history

    conan.sh脚本

    #!/bin/bash
    
    export PATH=$PATH:/usr/jdk8/bin
    
    project=
    server_port=8080
    log=
    backup_dir=
    
    help() {
        echo "usage: $0 -f PROJECT -p SERVER_PORT -l LOG -D BACKUP_DIR backup|stop|remove|start"
        echo "-------------------------"
        echo "多个命令可以按顺序执行,例如:$0 -f PROJECT -l LOG stop start"
        echo "PROJECT      项目路径"
        echo "SERVER_PORT  启动端口号,默认:8080"
        echo "LOG          日志路径"
        echo "BACKUP_DIR   备份目录"
        echo "-------------------------"
    }
    
    backup() {
        if [ ! $project ]
        then
            echo "项目路径不能为空"
            return
        fi
        if [ ! $backup_dir ]
        then
            echo "备份目录不能为空"
            return
        fi
    
        suffix=$(date +%Y%m%d%H%M%S);
        backup_name=${project##*/}.$suffix
        backup=$backup_dir/$backup_name
    
        echo "原项目 $project"
        echo "备份到 $backup"
        echo "  脚本 cp $project $backup"
        cp $project $backup
    }
    
    stop() {
        if [ ! $project ]
        then
            echo "项目路径不能为空"
            return
        fi
    
        project_name=${project##*/}
    
        pid=$(ps -ef | grep "$project_name" | grep -v grep | grep -v conan.sh | awk '{print $2}')
        if [ $pid ]
        then
            echo "  关闭 $project_name"
            echo "  进程 $(ps -ef | grep "$project_name" | grep -v grep)"
            echo "  脚本 kill $pid"
            kill $pid
        fi
    }
    
    remove() {
        if [ ! $project ]
        then
            echo "项目路径不能为空"
            return
        fi
    
        echo "  删除 $project"
        echo "  脚本 rm -f $project"
        rm -f $project
    }
    
    start() {
        if [ ! $project ]
        then
            echo "项目路径不能为空"
            return
        fi
        if [ ! $log ]
        then
            echo "日志路径不能为空"
            return
        fi
    
        project_name=${project##*/}
    
        pid=$(ps -ef | grep "$project_name" | grep -v grep | grep -v conan.sh | awk '{print $2}')
        if [ ! $pid  ]
        then
            script="java -jar $project --server.port=$server_port"
            echo "  启动 $project"
            echo "  脚本 nohup $script > $log 2>&1 &"
            nohup $script > $log 2>&1 &
        fi
    }
    
    while getopts "f: p: l: D:" opt
    do
        case $opt in
            f)
                project=$(ls $OPTARG)
                ;;
            p)
                server_port=$OPTARG
                ;;
            l)
                log=$OPTARG
                ;;
            D)
                backup_dir=$OPTARG
                ;;
            ?)
                ;;
        esac
    done
    
    shift $(($OPTIND - 1))
    
    echo "按顺序执行 $@"
    for act in $@
    do
        case $act in
            backup)
                backup
                ;;
            stop)
                stop
                ;;
            remove)
                remove
                ;;
            start)
                start
                ;;
            *)
                echo "unknow argument"
                ;;
        esac
    done
    

    PS:本文使用的是jenkins-2.46.3

    相关文章

      网友评论

          本文标题:Jenkins 持续集成工具 实践中的那些事

          本文链接:https://www.haomeiwen.com/subject/tiduqxtx.html