2.Jenkins之Pipeline使用

概念

是一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或者多个节点 的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。

优势

代码:Pipeline以代码的形式实现,通常被检入源代码控制,使团队能够编辑,审查和迭代其传送流程。
持久:无论是计划内的还是计划外的服务器重启,Pipeline都是可恢复的。
可停止:Pipeline可接收交互式输入,以确定是否继续执行Pipeline。
多功能:Pipeline支持现实世界中复杂的持续交付要求。它支持fork/join、循环执行,并行执行任务的功能。
可扩展:Pipeline插件支持其DSL的自定义扩展 ,以及与其他插件集成的多个选项。

插件安装

需要安装插件Pipeline

安装后,在Jenkins中"新建Item"时会出现一个选项

image-20220410135901485

PipeLine语法

#声明式:
pipeline {
    agent any
    stages { #整个流水线的所有执行阶段。通常stages只有1个,里面包含多个stage
        stage('拉取代码' ) { #流水线中的某个阶段,可能出现多个。一般分为拉取代码,编译构建,部署等阶段。
            steps { #代表一个阶段内需要执行的逻辑。steps里面是shell脚本,git拉取代码,ssh远程发布等任意内容
                echo '拉取代码'
            }
        }
        stage('编译代码 ') {
            steps {
                echo '编译代码'
            }
        }
        stage('发布运行 ') {
            steps {
                echo '发布运行'
            }
        }
    }
}
#脚本式:
node {
    stage('拉取代码' ) {
        echo '拉取代码'
    }
    stage('编译代码 ') {
        echo '编译代码'
    }
    stage('发布运行 ') {
        echo '发布运行'
    }
}

实现拉取->编译->部署

整体配置项没变,和第一篇一样,只不过展现的形式变了

最终生成好的PipeLine

不论是声明式还是脚本式,实际执行的内容一样,只不过结构不同

node {
    stage('拉取代码' ) {
        checkout([$class: 'GitSCM', branches: [[name: '*/master1']], extensions: [], userRemoteConfigs: [[credentialsId: '1dabcacf-ffda-4c45-ad9b-32f9a640f4d9', url: 'https://gitee.com/RollBack2010/jekins-study.git']]])
    }
    stage('编译代码 ') {
        sh 'mvn clean package'
    }
    stage('发布运行 ') {
    sshPublisher(publishers: [sshPublisherDesc(configName: 'jarPath', transfers: [sshTransfer(cleanRemote: false, excludes: '', 		execCommand: '''cd /usr/local/project
./start.sh''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/demo-0.0.1-SNAPSHOT.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false), sshPublisherDesc(configName: 'jarPath1', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''cd /usr/local/project1
./start.sh''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/demo-0.0.1-SNAPSHOT.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])     
    }
}

命令生成方式

进入“流水线语法”生成页面

image-20220410152909767

拉取

image-20220410153031353

image-20220410153133005

编译

image-20220410153234422

部署

image-20220410153432237

执行Build

会完成下载、编译、部署、启动流程

PipeLine脚本存放到项目中

以上都是将命令存放到Jenkins中,这样无法记录脚本修改记录,也容易丢失,所以将脚本放到项目中,通过git进行管理

创建Jenkinsfile

存放到项目根目录,名字也可以改,不过Jenkins默认找这个,文件内容就是上面的脚本内容

image-20220410154534691

Jenkins中修改配置

image-20220410154817695

执行Build

会完成下载、编译、部署、启动流程

通过参数构建

上面拉取代码的分支都是写死在Jenkinsfile中,现在把这个设置为传入变量

第一步,jenkins项目配置

image-20220410194940616

第二步,修改Jenkinsfile脚本

  #*/master1 -> */${branch}
  #由
  checkout([$class: 'GitSCM', branches: [[name: '*/master1']], extensions: [], userRemoteConfigs: [[credentialsId: 'ff8ba3ca-be5f-4535-bb37-08de5ef208f9', url: 'https://gitee.com/RollBack2010/jekins-study.git']]])
  #修改为
 checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: 'ff8ba3ca-be5f-4535-bb37-08de5ef208f9', url: 'https://gitee.com/RollBack2010/jekins-study.git']]])

第三步,使用

image-20220410195153859

对于在“片段生成器”中未提供的插件使用

我想实现,拉取代码编译完成后,在部署前,先去对应服务器上把正在运行的服务停止,否则直接启动会报端口占用

第一步,安装插件SSH Pipeline Steps

image-20220410200346979

第二步,发现插件未提供代码片段生成

image-20220410200527018

第三步,打开对应的README

根据文档及各种搜索引擎实现

本次实现的完整Pipeline脚本

#第一步.先定义要去哪台服务器上执行停止脚本
def remote = [:]
remote.name = 'test' #起个名字
remote.host = '192.168.0.104' #服务器ip
remote.user = 'root'
remote.password = '123'
remote.allowAnyHosts = true

pipeline {
    agent any
    stages {
        stage('拉取代码' ) {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: 'ff8ba3ca-be5f-4535-bb37-08de5ef208f9', url: 'https://gitee.com/RollBack2010/jekins-study.git']]])
            }
        }
        stage('编译代码 ') {
            steps {
                sh 'mvn clean package'
            }
        }
        #第二步.添加一个管道
        stage('停止服务 ') {
            steps {
            #执行对应服务器上的一个脚本
                sshCommand remote: remote, command: "bash /usr/local/project/stop.sh"
            }
        }
        stage('发布运行 ') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'jarPath', transfers: [sshTransfer(cleanRemote: false, excludes: '', 		execCommand: '''cd /usr/local/project
./start.sh''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/demo-0.0.1-SNAPSHOT.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])     
            }
        }
    }
}

stop.sh脚本内容

#!/bin/sh -l

#在jenkins "Execute shell"中先刷新环境变量,否则会报各种找不到命令
source /etc/profile

#定义一个全局变量,用于存放服务的进程
processNum
#定义个函数,用于获得进程,并将进程赋值给上面定义的变量
#这个函数逻辑为:
#	1.通过jps -l命令,获得所有运行的java进程
#	2.通过awk命令,查询jar包叫 “project-0.0.1-SNAPSHOT.jar”的(此处可改成各种正则条件匹配)
#	3.通过cut命令,根据“ ”切分awk匹配出来的记录,然后获得进程
function checkProcessNum()
{
        processNum=$(jps -l | awk -F " " '/demo-0.0.1-SNAPSHOT.jar/' | cut -d " " -f 1)
}
#调用一下函数,获得进程
checkProcessNum

echo "当前运行进程号为:"$processNum"执行kill命令"

#执行kill命令,当然,这块应该再加个if判断进程是否存在更好
kill $processNum

echo "kill命令已执行,循环检查是否正常停止"
#isDown:0:服务未停 1:服务已停
isDown=0

#循环检查是否停止,因为可能有线程还未执行完,无法停止
while [ $isDown -eq 0 ]
        do
          echo "每隔1秒查询下项目端口是否存在,存在说明还没停止"
          sleep 1s
          #每等待1秒调用函数查询进程是否存在
          checkProcessNum

          if [ ! $processNum ]
                then
                #进程终止了,停止循环
                        echo "服务停止了"
                        isDown=1
          elif [  $processNum ]
                then
                        echo "服务还在运行中"
          fi
          done

echo "服务已停止"
posted @ 2022-04-26 16:48  RollBack2010  阅读(3248)  评论(0编辑  收藏  举报