zoukankan      html  css  js  c++  java
  • 基于Java+Spring Boot开源项目JeeSite的Jenkins持续交付介绍

    一、实战项目介绍- JeeSite

    • 基于Spring Boot 2.0
    • 数据存储MySQL
    • 语言:Java
    • 规模大小:适中,适合初学者

    源码地址:https://gitee.com/thinkgem/jeesite4 ,感谢原作者
    本次项目演练地址:https://gitee.com/sfboy/iJeeSite4 ,在原作者的项目上,增加了Pipline持续集成的脚本,便于实战使用

    二、环境准备

    Spring Boot项目运行配置:MySQL+Java+Maven
    MySQL安装参考:https://www.cnblogs.com/feng0815/p/14041558.html
    Maven安装参考: https://www.cnblogs.com/feng0815/p/14354226.html
    Java安装参考:自行百度。。

    三、项目配置、调试、运行

    3.1 初始化

    • 打开 JeeSite4/web/src/main/resources/config/application.yml,填写数据库配置(地址、IP端口、用户名、密码)
    • 进入项目路径 JeeSite4/web/bin,运行初始化脚本程序init-data.sh(Windows下运行init-data.bat)

    初始化脚本用来创建初始数据,初始化前要保证数据库中有jeesite数据库,否则会造成无法连接jeesite数据库,初始化失败

    开始执行

    执行结束

    3.2 配置项目

    3.2.1 使用IDE编译

    • 添加JeeSite4/root/pom.xml Maven根节点到IDE的maven view中,其余依赖module会根据配置一起导入

      Maven编译、打包
      在Maven view 中选中JeeSite Root下Lifecycle中的clean + install,然后单击运行按钮

    3.2.2 在命令行编译

    进入到JeeSite4/root目录下,运行mvn clean install

    3.3 运行项目demo

    3.3.1 在IDE运行

    展开JeeSite Web → Plugins → spring-boot → spring-boot:run ,单击运行

    运行成功

    访问项目:http://localhost:8980/a/login

    输入用户名system,密码admin,点击登录

    3.3.2 在命令行运行

    进入到JeeSite4/web目录下,运行:mvn clean spring-boot:run -Dmaven.test.skip=true(Dmaven.test.skip=true,不运行单元测试)

    运行成功

    四、Tomcat部署持续交互实战

    4.1 Tomcat运行和配置入门

    下载,官网:https://tomcat.apache.org/

    直接解压到安装目录即可

    Tomcat基本配置

    • 启动:bin/startup.sh
    • 停止:bin/shutdown.sh
    • 配置文件:conf/server.xml(配置端口号)
    • 日志:logs/catalina.out

    4.2 使用Jenkins Pipline任务部署Spring应用到Tomcat

    4.2.1 Jenkins参数配置,设置Pipline脚本中所需的参数


    创建Jenkins Pipline任务

    设置代码分支,默认分支为master

    4.2.2 配置Pipline脚本


    运行,构建任务

    构建成功,打开项目页面:http://localhost:8080/a/login

    Pipline代码如下(Scripted Pipeline):

    node('master') {
        stage('同步源码') {
                git([url: 'https://gitee.com/sfboy/iJeeSite4.git', branch: '${branch}'])
        }
    
    stage(<span class="hljs-string">'maven编译打包'</span>) {
        sh <span class="hljs-string">'''
            . ~/.bash_profile
            
            export pwd=`pwd`
            export os_type=`uname`
            cd web/src/main/resources/config
            if [[ "${os_type}" == "Darwin" ]]; then
                sed -i "" "s/mysql_ip/${mysql_ip}/g" application.yml
                sed -i "" "s/mysql_port/${mysql_port}/g" application.yml
                sed -i "" "s/mysql_user/${mysql_user}/g" application.yml
                sed -i "" "s/mysql_pwd/${mysql_pwd}/g" application.yml
            else
                sed -i "s/mysql_ip/${mysql_ip}/g" application.yml
                sed -i "s/mysql_port/${mysql_port}/g" application.yml
                sed -i "s/mysql_user/${mysql_user}/g" application.yml
                sed -i "s/mysql_pwd/${mysql_pwd}/g" application.yml
            fi
            
            cd $pwd/root
            mvn clean install -Dmaven.test.skip=true
            
            cd $pwd/web
            mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
        '''</span>
    }
    
    stage(<span class="hljs-string">'停止 tomcat'</span>) {
        sh <span class="hljs-string">'''
            ## 停止tomcat的函数, 参数$1带入tomcat的路径$TOMCAT_PATH
            killTomcat()
            {
                pid=`ps -ef|grep $1|grep java|awk '{print $2}'`
                echo "tomcat Id list :$pid"
                if [ "$pid" = "" ]
                then
                  echo "no tomcat pid alive"
                else
                  kill -9 $pid
                fi
            }
            ## 停止Tomcat
            killTomcat $tomcat_home
        '''</span>
    }
    
    stage(<span class="hljs-string">'清理环境'</span>) {
        sh <span class="hljs-string">'''
            ## 删除原有war包
            rm -f $tomcat_home/webapps/ROOT.war
            rm -rf $tomcat_home/webapps/ROOT
        '''</span>
    }
    
    stage(<span class="hljs-string">'部署新的war包'</span>) {
        sh <span class="hljs-string">'''
            cp web/target/web.war $tomcat_home/webapps/
            cd $tomcat_home/webapps
            mv web.war ROOT.war
        '''</span>
    }
    
    stage(<span class="hljs-string">'启动tomcat'</span>) {
        sh <span class="hljs-string">'''
            JENKINS_NODE_COOKIE=dontkillme
            cd $tomcat_home/bin
            sh startup.sh
        '''</span>
    }
    

    }

    五、docker部署持续交付实战


    Pipline脚本(Declarative Pipeline)

    pipeline {
        agent {
            label 'master'
        }
    
    environment {
        docker_image_name = <span class="hljs-string">'jeesite4'</span>
        docker_container_name = <span class="hljs-string">'iJeesite4'</span>
        PATH = <span class="hljs-string">"/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"</span>
    }
    
    parameters {
        string(name: <span class="hljs-string">'branch'</span>, defaultValue: <span class="hljs-string">'master'</span>, description: <span class="hljs-string">'Git branch'</span>)
    }
    
    stages{
        stage(<span class="hljs-string">'同步源码'</span>) {
            steps {
                git url:<span class="hljs-string">'https://gitee.com/sfboy/iJeeSite4.git'</span>, branch:<span class="hljs-string">'$branch'</span>
            }
        }
    
        stage(<span class="hljs-string">'设定配置文件'</span>){
            steps{
                sh <span class="hljs-string">'''
                    . ~/.bash_profile
            
                    export os_type=`uname`
                    cd ${WORKSPACE}/web/bin/docker
                    if [[ "${os_type}" == "Darwin" ]]; then
                        sed -i "" "s/mysql_ip/${mysql_docker_ip}/g" application-prod.yml
                        sed -i "" "s/mysql_port/${mysql_port}/g" application-prod.yml
                        sed -i "" "s/mysql_user/${mysql_user}/g" application-prod.yml
                        sed -i "" "s/mysql_pwd/${mysql_pwd}/g" application-prod.yml
                    else
                        sed -i "s/mysql_ip/${mysql_docker_ip}/g" application-prod.yml
                        sed -i "s/mysql_port/${mysql_port}/g" application-prod.yml
                        sed -i "s/mysql_user/${mysql_user}/g" application-prod.yml
                        sed -i "s/mysql_pwd/${mysql_pwd}/g" application-prod.yml
                    fi
                '''</span>
            }
        }
    
        stage(<span class="hljs-string">'Maven 编译'</span>){
            steps {
                sh <span class="hljs-string">'''
                    . ~/.bash_profile 
                                      
                    cd ${WORKSPACE}/root
                    mvn clean install -Dmaven.test.skip=true
                    
                    cd ${WORKSPACE}/web
                    mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
                '''</span>
            }
        }
    
        stage(<span class="hljs-string">'停止 / 删除 现有Docker Container/Image '</span>){
            steps {
                script{
        
                    <span class="hljs-keyword">try</span>{
                        sh <span class="hljs-string">'docker stop $docker_container_name'</span>
                    }catch(exc){
                        echo <span class="hljs-string">"The container $docker_container_name does not exist"</span>
                    }
    
                    <span class="hljs-keyword">try</span>{
                        sh <span class="hljs-string">'docker rm $docker_container_name'</span>
                    }catch(exc){
                        echo <span class="hljs-string">"The container $docker_container_name does not exist"</span>
                    }
    
                    <span class="hljs-keyword">try</span>{
                        sh <span class="hljs-string">'docker rmi $docker_image_name'</span>
                    }catch(exc){
                        echo <span class="hljs-string">"The docker image $docker_image_name does not exist"</span>
                    }
                }
            }
        }
    
        stage(<span class="hljs-string">'生成新的Docker Image'</span>){
            steps {
                sh <span class="hljs-string">'''
                    . ~/.bash_profile
                    cd ${WORKSPACE}/web/bin/docker
                    rm -f web.war
                    cp ${WORKSPACE}/web/target/web.war .
                    docker build -t $docker_image_name .
                '''</span>
            }
        }
    
        stage(<span class="hljs-string">'启动新Docker实例'</span>){
            steps {
                sh <span class="hljs-string">'''
                    docker run -d --name $docker_container_name -p 8981:8980 $docker_image_name
                '''</span>
            }
        }
    }
    

    }



    六、生产与测试环境分离持续交付实战

    需要在Pipline脚本中区分环境,具体脚本如下

    pipeline {
        agent {
            label 'master'
        }
    
    environment {
        docker_image = <span class="hljs-string">'jeesite4'</span>
        docker_container = <span class="hljs-string">'iJeesite4'</span>
        PATH = <span class="hljs-string">"/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"</span>
    }
    
    parameters {
        string(name: <span class="hljs-string">'branch'</span>, defaultValue: <span class="hljs-string">'master'</span>, description: <span class="hljs-string">'Git branch'</span>)
        choice(name: <span class="hljs-string">'env'</span>, choices: [<span class="hljs-string">'prod'</span>, <span class="hljs-string">'qa'</span>], description: <span class="hljs-string">'Environment Type'</span>)
    }
    
    stages{
        stage(<span class="hljs-string">'同步源码'</span>) {
            steps {
                git url:<span class="hljs-string">'https://gitee.com/sfboy/iJeeSite4.git'</span>, branch:<span class="hljs-string">'<span class="hljs-subst">${branch}</span>'</span>
            }
        }
    
        stage(<span class="hljs-string">'设定配置文件'</span>){
            steps{
                sh <span class="hljs-string">'''
                    . ~/.bash_profile         
                    
                    if [[ "<span class="hljs-subst">${env}</span>" == "prod" ]]; then
                        export mysql_ip=<span class="hljs-subst">${mysql_prod_ip}</span>
                        export mysql_port=<span class="hljs-subst">${mysql_prod_port}</span>
                    else
                        export mysql_ip=<span class="hljs-subst">${mysql_qa_ip}</span>
                        export mysql_port=<span class="hljs-subst">${mysql_qa_port}</span>
                    fi
                    
                    export os_type=`uname`
                    cd <span class="hljs-subst">${WORKSPACE}</span>/web/bin/docker
                    if [[ "<span class="hljs-subst">${os_type}</span>" == "Darwin" ]]; then
                        sed -i "" "s/mysql_ip/<span class="hljs-subst">${mysql_ip}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "" "s/mysql_port/<span class="hljs-subst">${mysql_port}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "" "s/mysql_user/<span class="hljs-subst">${mysql_user}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "" "s/mysql_pwd/<span class="hljs-subst">${mysql_pwd}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "" "s/&lt;env&gt;/<span class="hljs-subst">${env}</span>/g" Dockerfile-param
                    else
                        sed -i "s/mysql_ip/<span class="hljs-subst">${mysql_ip}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "s/mysql_port/<span class="hljs-subst">${mysql_port}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "s/mysql_user/<span class="hljs-subst">${mysql_user}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "s/mysql_pwd/<span class="hljs-subst">${mysql_pwd}</span>/g" application-<span class="hljs-subst">${env}</span>.yml
                        sed -i "s/&lt;env&gt;/<span class="hljs-subst">${env}</span>/g" Dockerfile-param
                    fi
                '''</span>
            }
        }
    
        stage(<span class="hljs-string">'Maven 编译'</span>){
            steps {
                sh <span class="hljs-string">'''
                    . ~/.bash_profile  
    
                    cd <span class="hljs-subst">${WORKSPACE}</span>/root
                    mvn clean install -Dmaven.test.skip=true
                    
                    cd <span class="hljs-subst">${WORKSPACE}</span>/web
                    mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
                '''</span>
            }
        }
    
        stage(<span class="hljs-string">'停止 / 删除 现有Docker Container/Image '</span>){
            steps {
                script{
                    <span class="hljs-keyword">try</span>{
                        sh <span class="hljs-string">'docker stop <span class="hljs-subst">$docker_container</span>-<span class="hljs-subst">$env</span>'</span>
                    }<span class="hljs-keyword">catch</span>(exc){
                        echo <span class="hljs-string">"The container <span class="hljs-subst">$docker_container</span>-<span class="hljs-subst">${params.env}</span> does not exist"</span>
                    }
    
                    <span class="hljs-keyword">try</span>{
                        sh <span class="hljs-string">'docker rm <span class="hljs-subst">$docker_container</span>-<span class="hljs-subst">$env</span>'</span>
                    }<span class="hljs-keyword">catch</span>(exc){
                        echo <span class="hljs-string">"The container <span class="hljs-subst">$docker_container</span>-<span class="hljs-subst">${params.env}</span> does not exist"</span>
                    }
    
                    <span class="hljs-keyword">try</span>{
                        sh <span class="hljs-string">'docker rmi <span class="hljs-subst">$docker_image</span>-<span class="hljs-subst">$env</span>'</span>
                    }<span class="hljs-keyword">catch</span>(exc){
                        echo <span class="hljs-string">"The docker image <span class="hljs-subst">$docker_image</span>-<span class="hljs-subst">${params.env}</span> does not exist"</span>
                    }
                }
            }
        }
    
        stage(<span class="hljs-string">'生成新的Docker Image'</span>){
            steps {
                sh <span class="hljs-string">'''
                    cd <span class="hljs-subst">${WORKSPACE}</span>/web/bin/docker
                    rm -f web.war
                    cp <span class="hljs-subst">${WORKSPACE}</span>/web/target/web.war .
                    docker build -t <span class="hljs-subst">$docker_image</span>-<span class="hljs-subst">$env</span> -f Dockerfile-param .
                '''</span>
            }
        }
    
        stage(<span class="hljs-string">'启动新Docker实例'</span>){
            steps {
                sh <span class="hljs-string">'''
                    if [[ "<span class="hljs-subst">$env</span>" == "prod" ]]; then
                        export port="8888"
                    else
                        export port="8811"
                    fi
                    
                    docker run -d --name <span class="hljs-subst">$docker_container</span>-<span class="hljs-subst">$env</span> -p <span class="hljs-subst">$port</span>:8980 <span class="hljs-subst">$docker_image</span>-<span class="hljs-subst">$env</span>
                '''</span>
            }
        }
    }
    

    }

    dockerfile

    FROM frolvlad/alpine-java:jdk8-slim
    MAINTAINER ThinkGem@163.com
    ENV TZ "Asia/Shanghai"
    ENV LANG C.UTF-8
    VOLUME /tmp
    

    WORKDIR /app
    ADD web.war .
    RUN jar -xvf web.war

    WORKDIR /app/WEB-INF
    ENV JAVA_OPTS "-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"
    ENV JAVA_OPTS "$JAVA_OPTS -Dspring.profiles.active=<env>"

    ADD application-<env>.yml ./classes/config

    ENTRYPOINT java -cp /app $JAVA_OPTS org.springframework.boot.loader.WarLauncher

    EXPOSE 8980

    在Jenkins中配置好Pipline脚本中所需的MySQL变量信息

    创建Pipline任务,设置Pipline脚本

    由于我们第一次执行时,脚本里的parameter参数无法同步到Jenkins是里,所以第一次执行会报错,当我们刷新页面是就会发现参数已经同步了

    然后我们选择测试环境,再次build即可

    build完成

    打开测试环境:http://127.0.0.1:8811/a/login

    然后我们再build成产环境

    build完成

    打开成产环境:http://localhost:8888/a/login

    查看生产环境和测试环境的docker容器

    ok,完结,撒花~~

  • 相关阅读:
    Ed Chi 的 long range dependence works
    论文阅读:Stochastic Weight Completion for Road Networks using Graph Convolutional Networks
    论文阅读:HOP-Rec: High-Order Proximity for Implicit Recommendation
    温故BERT之Transformer
    论文阅读:Are We Really Making Much Progress-A Worrying Analysis of Recent Neural Recommendatin Approaches
    使用ffmpeg进行媒体格式转换
    使用ghostscript将pdf转图片
    linux下使用libreoffice将Office文档转PDF
    nginx指定文件路径有两种方式root和alias
    CentOS下的SVN服务器搭建过程
  • 原文地址:https://www.cnblogs.com/R-bear/p/15045752.html
Copyright © 2011-2022 走看看