美文网首页
Jenkins Pipeline + Gogs 实现 Sprin

Jenkins Pipeline + Gogs 实现 Sprin

作者: 程序猿卖水果 | 来源:发表于2020-02-07 15:10 被阅读0次

    [TOC]

    前言

    CI/CD是什么呢?在软件开发过程中存在这繁琐的重复的“构建”、“发布”、“测试”工作,把这些工作进行流程化自动化的实践过程则可称之为CI/CD。而这个过程种可能需要到Kuberneters、Docker in Docker 、Pipeline等丰富的工具链和知识储备,而团队中又没有Kuberneters实现自动部署?我们团队成员也没有太多时间学习掌握Pipeline呢?完成自动构建后又如何实现jar的自动上传和优雅地重启呢?面对这些问题该如何解决呢?而这里将通过 SSH 将应用部署到远程主机以满足非容器化的场景需求。通过Jenkinsfile以及scm模式实现项目零配置。最后通过sh脚本实现程序地发布和优雅地重启。

    Jenkins 部署

    环境准备

    安装 Docker
    配置 yum 源
    ## 配置默认源
    ## 备份
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    
    ## 下载阿里源
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    
    ## 刷新
    yum makecache fast
    
    
    
    ## 重建yum缓存
    yum clean all
    yum makecache fast
    yum -y update
    
    安装 Docker

    下载docker的yum源文件

    yum -y install yum-utils device-mapper-persistent-data lvm2
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    

    这里指定 Docker 版本,可以先查看支持的版本

    [root@localhost ~]# yum list docker-ce --showduplicates |sort -r               
     * updates: mirrors.aliyun.com
    Loading mirror speeds from cached hostfile
    Loaded plugins: fastestmirror
     * extras: mirrors.aliyun.com
     * epel: hkg.mirror.rackspace.com
    docker-ce.x86_64            3:19.03.2-3.el7                     docker-ce-stable
    docker-ce.x86_64            3:19.03.1-3.el7                     docker-ce-stable
    docker-ce.x86_64            3:19.03.0-3.el7                     docker-ce-stable
    docker-ce.x86_64            3:18.09.9-3.el7                     docker-ce-stable
    ...
     * base: mirrors.aliyun.com
    

    目前最新版本为19.03,指定下载18.09

    yum install -y docker-ce-18.09.9-3.el7
    systemctl enable docker
    systemctl start docker
    
    新建 Jenkins 专用用户组和用户
    groupadd -g 1000 jenkins
    useradd -u 1000 -g 1000 -s /sbin/nologin jenkins
    
    安装 Maven 工具
    ## 下载 Maven
    wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
    
    ## 解压至指定目录供后续调用
    tar xzf apache-maven-3.6.3-bin.tar.gz /opt
    

    安装 Jenkins

    通过 Docker 安装 Jenkins
    docker run -d --name jenkinsci --restart=always -p 1080:8080 -v /home/jenkins:/var/jenkins_home -v /opt/apache-maven-3.6.3:/opt/maven dockerhub.azk8s.cn/jenkins/jenkins:2.204.2
    
    解锁 Jenkins

    当您第一次访问新的Jenkins实例时,系统会要求您使用自动生成的密码对其进行解锁。

    1. 浏览到 http://localhost:1080(或安装时为Jenkins配置的任何端口),并等待 解锁 Jenkins 页面出现。
      avatar
    2. 从Jenkins控制台日志输出中,复制自动生成的字母数字密码(在两组星号之间


      avatar
    安装插件

    通过Jenkins中的Manage Jenkins > Manage Plugins 安装本案用到得插件 。

    • Timestamper
    • Pipeline
    • Pipeline: Stage View
    • Generic Webhook Trigger
    • Git
    • Email Extension
    • Mailer
    • SSH Pipeline Steps
    • Gogs

    部署项目

    环境准备

    部署 Java 运行环境
    ## 安装 OpenJDK
    yum install -y java-1.8.0-openjdk
    
    ## 配置 JAVA_HOME 环境变量
    
    cat <<EOF >  /etc/profile
    JAVA_HOME=/usr/lib/jvm/java
    CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
    PATH=${PATH}:${JAVA_HOME}/bin:/usr/local/bin
    export JAVA_HOME CLASSPATH PATH
    EOF
    source /etc/profile
    
    配置 SSH 证书访问

    生成 SSH 证书

    ssh-keygen -t rsa -b 4096
    

    修改服务器 ssh 配置文件

    vi /etc/ssh/sshd_config
    
    
    ## 是否允许用户自行使用成对的密钥系统进行登入行为,仅针对 version 2。
    ## 至于自制的公钥数据就放置于用户家目录下的 .ssh/id_rsa.pub
    RSAAuthentication yes
    PubkeyAuthentication yes
    AuthorizedKeysFile %h/.ssh/id_rsa.pub
    

    重启 SSH

    systemctl restart sshd
    

    验证 SSH 证书登录过

    ssh -h localhost -i ~/.ssh/id_rsa -l root
    
    为 Jenkins 配置 SSH 部署私钥
    1. 在凭据-->系统中找到“全局凭据”


      avatar
    2. 添加一个全局凭据,类型选择为“SSH Username with private key”


      avatar
    3. 将私钥粘贴到“private Key”中,并将ID设置为 root10.168.1.42 供后续使用,然后保存


      avatar
      avatar
    Gogs 仓库准备
    1. 新建 Spring Boot 项目


      avatar
    2. 在项目中增加 Jenkinsfile 与 Launch 文件,并推送到Gogs仓库


      avatar
    3. 根据项目实际情况修改 Jenkinsfile 配置

      avatar
      Note:
    • token 必须根据不同项目设置为不同的值,供 Jenkins 识别不同项目
    • 如需对应用设置不同端口或profile,可通过 java_opts 配置
      • 将端口设置为 1999 则 java_opts = "-Dserver.port=1999"
      • 使用 dev profile 则 java_opts = "-Dspring.profiles.active=dev"

    部署项目

    1. 新建一个任务


      avatar
    2. 输入自己任务的名称,然后选择流水线,流水线才是pipeline。


      avatar
    3. 确认之后管理界面,如果做过了解的应该知道,piepeline有两种方式,一种是直接写script另一种是引入SCM。这里使用第二种方式


      avatar
    4. 保存配置后进入项目界面,点击立即构建,稍等片刻待项目构建完成,并查看项目构建日志。


      avatar
      avatar
    Started by user admin
    Obtained Jenkinsfile from git http://10.168.1.21:3000/dtseaci/hello.git
    Running in Durability level: MAX_SURVIVABILITY
    [Pipeline] Start of Pipeline
    [Pipeline] node
    Running on Jenkins in /var/jenkins_home/workspace/demo
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Declarative: Checkout SCM)
    [Pipeline] checkout
    using credential d6b004da-0be9-4d1b-945a-8ccdc42ad6f4
    Cloning the remote Git repository
    Cloning repository http://10.168.1.21:3000/dtseaci/hello.git
     > git init /var/jenkins_home/workspace/demo # timeout=10
    Fetching upstream changes from http://10.168.1.21:3000/dtseaci/hello.git
     > git --version # timeout=10
    using GIT_ASKPASS to set credentials 
     > git fetch --tags --progress -- http://10.168.1.21:3000/dtseaci/hello.git +refs/heads/*:refs/remotes/origin/* # timeout=10
     > git config remote.origin.url http://10.168.1.21:3000/dtseaci/hello.git # timeout=10
     > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
     > git config remote.origin.url http://10.168.1.21:3000/dtseaci/hello.git # timeout=10
    Fetching upstream changes from http://10.168.1.21:3000/dtseaci/hello.git
    using GIT_ASKPASS to set credentials 
     > git fetch --tags --progress -- http://10.168.1.21:3000/dtseaci/hello.git +refs/heads/*:refs/remotes/origin/* # timeout=10
     > git rev-parse refs/remotes/origin/dev^{commit} # timeout=10
     > git rev-parse refs/remotes/origin/origin/dev^{commit} # timeout=10
    Checking out Revision adc94be7293c9c894a7122934d1be2c6c6f89953 (refs/remotes/origin/dev)
     > git config core.sparsecheckout # timeout=10
     > git checkout -f adc94be7293c9c894a7122934d1be2c6c6f89953 # timeout=10
    Commit message: "ci"
    First time build. Skipping changelog.
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] withEnv
    [Pipeline] {
    [Pipeline] timestamps
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Prepare)
    [Pipeline] echo
    14:16:39  1. Prepare Stage
    [Pipeline] checkout
    14:16:39  using credential d6b004da-0be9-4d1b-945a-8ccdc42ad6f4
    14:16:39   > git rev-parse --is-inside-work-tree # timeout=10
    14:16:39  Fetching changes from the remote Git repository
    14:16:39   > git config remote.origin.url http://10.168.1.21:3000/dtseaci/hello.git # timeout=10
    14:16:39  Fetching upstream changes from http://10.168.1.21:3000/dtseaci/hello.git
    14:16:39   > git --version # timeout=10
    14:16:39  using GIT_ASKPASS to set credentials 
    14:16:39   > git fetch --tags --progress -- http://10.168.1.21:3000/dtseaci/hello.git +refs/heads/*:refs/remotes/origin/* # timeout=10
    14:16:39   > git rev-parse refs/remotes/origin/dev^{commit} # timeout=10
    14:16:39   > git rev-parse refs/remotes/origin/origin/dev^{commit} # timeout=10
    14:16:39  Checking out Revision adc94be7293c9c894a7122934d1be2c6c6f89953 (refs/remotes/origin/dev)
    14:16:39   > git config core.sparsecheckout # timeout=10
    14:16:39   > git checkout -f adc94be7293c9c894a7122934d1be2c6c6f89953 # timeout=10
    14:16:39  Commit message: "ci"
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] stage
    [Pipeline] { (Maven)
    [Pipeline] echo
    14:16:39  2. Maven Stage
    [Pipeline] script
    [Pipeline] {
    [Pipeline] sh
    14:16:39  + /opt/maven/bin/mvn package
    14:16:41  [INFO] Scanning for projects...
    14:16:41  [INFO] 
    14:16:41  [INFO] -----------------------< net.dtsea.dtseac:hello >-----------------------
    14:16:41  [INFO] Building demo 0.0.1-SNAPSHOT
    14:16:41  [INFO] --------------------------------[ jar ]---------------------------------
    14:16:41  [INFO] 
    14:16:41  [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ hello ---
    14:16:42  [INFO] Using 'UTF-8' encoding to copy filtered resources.
    14:16:42  [INFO] Copying 1 resource
    14:16:42  [INFO] Copying 0 resource
    14:16:42  [INFO] 
    14:16:42  [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ hello ---
    14:16:42  [INFO] Changes detected - recompiling the module!
    14:16:42  [INFO] Compiling 1 source file to /var/jenkins_home/workspace/demo/target/classes
    14:16:42  [INFO] 
    14:16:42  [INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ hello ---
    14:16:42  [INFO] Using 'UTF-8' encoding to copy filtered resources.
    14:16:42  [INFO] skip non existing resourceDirectory /var/jenkins_home/workspace/demo/src/test/resources
    14:16:42  [INFO] 
    14:16:42  [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ hello ---
    14:16:42  [INFO] Changes detected - recompiling the module!
    14:16:42  [INFO] Compiling 1 source file to /var/jenkins_home/workspace/demo/target/test-classes
    14:16:42  [INFO] 
    14:16:42  [INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ hello ---
    14:16:43  [INFO] 
    14:16:43  [INFO] -------------------------------------------------------
    14:16:43  [INFO]  T E S T S
    14:16:43  [INFO] -------------------------------------------------------
    14:16:43  [INFO] Running net.dtsea.dtseac.hello.DemoApplicationTests
    14:16:43  06:16:43.770 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:43  06:16:43.776 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
    14:16:43  06:16:43.784 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
    14:16:43  06:16:43.808 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [net.dtsea.dtseac.hello.DemoApplicationTests] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
    14:16:43  06:16:43.822 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [net.dtsea.dtseac.hello.DemoApplicationTests], using SpringBootContextLoader
    14:16:43  06:16:43.826 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [net.dtsea.dtseac.hello.DemoApplicationTests]: class path resource [net/dtsea/dtseac/hello/DemoApplicationTests-context.xml] does not exist
    14:16:43  06:16:43.826 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [net.dtsea.dtseac.hello.DemoApplicationTests]: class path resource [net/dtsea/dtseac/hello/DemoApplicationTestsContext.groovy] does not exist
    14:16:43  06:16:43.827 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [net.dtsea.dtseac.hello.DemoApplicationTests]: no resource found for suffixes {-context.xml, Context.groovy}.
    14:16:43  06:16:43.827 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [net.dtsea.dtseac.hello.DemoApplicationTests]: DemoApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
    14:16:43  06:16:43.876 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:43.972 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [/var/jenkins_home/workspace/demo/target/classes/net/dtsea/dtseac/hello/DemoApplication.class]
    14:16:44  06:16:43.973 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration net.dtsea.dtseac.hello.DemoApplication for test class net.dtsea.dtseac.hello.DemoApplicationTests
    14:16:44  06:16:44.079 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [net.dtsea.dtseac.hello.DemoApplicationTests]: using defaults.
    14:16:44  06:16:44.080 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
    14:16:44  06:16:44.090 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/TransactionDefinition]
    14:16:44  06:16:44.091 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
    14:16:44  06:16:44.091 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@636be97c, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@50a638b5, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@1817d444, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@6ca8564a, org.springframework.test.context.support.DirtiesContextTestExecutionListener@50b472aa, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@31368b99, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@1725dc0f, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@3911c2a7, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@4ac3c60d, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@4facf68f]
    14:16:44  06:16:44.099 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.100 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.101 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.101 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.102 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.102 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.105 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@1ea9f6af testClass = DemoApplicationTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@6a192cfe testClass = DemoApplicationTests, locations = '{}', classes = '{class net.dtsea.dtseac.hello.DemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@68bbe345, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4bbfb90a, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@56aac163, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@536aaa8d], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true]], class annotated with @DirtiesContext [false] with mode [null].
    14:16:44  06:16:44.106 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.106 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [net.dtsea.dtseac.hello.DemoApplicationTests]
    14:16:44  06:16:44.126 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=-1}
    14:16:44  
    14:16:44    .   ____          _            __ _ _
    14:16:44   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    14:16:44  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    14:16:44   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    14:16:44    '  |____| .__|_| |_|_| |_\__, | / / / /
    14:16:44   =========|_|==============|___/=/_/_/_/
    14:16:44   :: Spring Boot ::       (v2.1.12.RELEASE)
    14:16:44  
    14:16:44  2020-02-07 06:16:44.754  INFO 12207 --- [           main] n.d.dtseac.hello.DemoApplicationTests    : Starting DemoApplicationTests on 0a9deba97ed1 with PID 12207 (started by jenkins in /var/jenkins_home/workspace/demo)
    14:16:44  2020-02-07 06:16:44.755  INFO 12207 --- [           main] n.d.dtseac.hello.DemoApplicationTests    : No active profile set, falling back to default profiles: default
    14:16:47  2020-02-07 06:16:46.686  INFO 12207 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
    14:16:47  2020-02-07 06:16:46.966  INFO 12207 --- [           main] n.d.dtseac.hello.DemoApplicationTests    : Started DemoApplicationTests in 2.833 seconds (JVM running for 3.681)
    14:16:47  [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.586 s - in net.dtsea.dtseac.hello.DemoApplicationTests
    14:16:47  2020-02-07 06:16:47.206  INFO 12207 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
    14:16:47  [INFO] 
    14:16:47  [INFO] Results:
    14:16:47  [INFO] 
    14:16:47  [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    14:16:47  [INFO] 
    14:16:47  [INFO] 
    14:16:47  [INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ hello ---
    14:16:47  [INFO] Building jar: /var/jenkins_home/workspace/demo/target/hello-0.0.1-SNAPSHOT.jar
    14:16:48  [INFO] 
    14:16:48  [INFO] --- spring-boot-maven-plugin:2.1.12.RELEASE:repackage (repackage) @ hello ---
    14:16:48  [INFO] Replacing main artifact with repackaged archive
    14:16:48  [INFO] ------------------------------------------------------------------------
    14:16:48  [INFO] BUILD SUCCESS
    14:16:48  [INFO] ------------------------------------------------------------------------
    14:16:48  [INFO] Total time:  7.420 s
    14:16:48  [INFO] Finished at: 2020-02-07T06:16:48Z
    14:16:48  [INFO] ------------------------------------------------------------------------
    [Pipeline] }
    [Pipeline] // script
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] stage
    [Pipeline] { (Deploy)
    [Pipeline] echo
    14:16:48  3. Deploy Stage
    [Pipeline] script
    [Pipeline] {
    [Pipeline] readMavenPom
    [Pipeline] sh
    14:16:48  + sed -i s/<API_NAME>/hello-0.0.1-SNAPSHOT/ Launch
    [Pipeline] sh
    14:16:49  + sed -i s/<JAVA_OPTS>/-Xms256m -Xmx512m/ Launch
    [Pipeline] withCredentials
    14:16:49  Masking supported pattern matches of $_keyfile or $_uname
    [Pipeline] {
    [Pipeline] sshCommand
    14:16:49  Executing command on dest[10.168.1.42]: mkdir -p /opt/dst**** sudo: false
    [Pipeline] sshPut
    14:16:49  Sending a file/directory to dest[10.168.1.42]: from: /var/jenkins_home/workspace/demo/Launch into: /opt/dst****
    [Pipeline] sshPut
    14:16:49  Sending a file/directory to dest[10.168.1.42]: from: /var/jenkins_home/workspace/demo/target/hello-0.0.1-SNAPSHOT.jar into: /opt/dst****
    [Pipeline] sshCommand
    14:16:50  Executing command on dest[10.168.1.42]: mv -f /opt/dst****/Launch /opt/dst****/Launch.sh sudo: false
    [Pipeline] sshCommand
    14:16:50  Executing command on dest[10.168.1.42]: chmod +x /opt/dst****/Launch.sh sudo: false
    [Pipeline] sshCommand
    14:16:50  Executing command on dest[10.168.1.42]: cd /opt/dst**** && ./Launch.sh restart sudo: false
    14:16:51  >>> api PID = 27892 begin kill 27892 <<<
    14:16:53  >>> /opt/dst****/hello-0.0.1-SNAPSHOT.jar is not running <<<
    14:16:53  >>> start /opt/dst****/hello-0.0.1-SNAPSHOT.jar successed PID=28031 <<<
    [Pipeline] }
    [Pipeline] // withCredentials
    [Pipeline] }
    [Pipeline] // script
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // timestamps
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // withEnv
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    
    1. 登录目标服务器通过PS查看进程已成功运行,并通过 get 8080端口获得程序输出。


      avatar

    设置 Gogs 钩子

    1. 添加Web钩子
      登录代码管理系统,进入仓库设置→管理Web钩子→添加Web钩子。


      avatar
    2. 设置web钩子的详情
      这里的推送地址是http://jenkins地址:端口号/generic-webhook-trigger/invoke?token=密钥,这里的密钥是要与前面在Jenkinsfile里面的密钥设置一致。触发web钩子的事件可以自己设置什么样的事件去触发jenkins的构建。
      avatar

    这里设置完了之后可以点击测试推送,点击测试记录可以看到发送给jenkins的推送详情了。其中ref就是推送过去的分支啦。以下的推送的内容都是可以通过设置jenkins变量来获得的。(底下红色圈出的部分是Jenkinsfile中配置的变量)


    avatar
    1. 验证钩子触发 Jenkins 自动构建
      在项目目录提交代码变更,并将提交信息填写为"ci test"便于查看,并推送。


      avatar

      片刻后 Jenkins 便构建完成,查看提交信息及日志发现项目由 Gogs 钩子触发构建完成。


      avatar
      avatar

    Note

    • Jenkinsfile
    pipeline{
        agent any
        environment {
            // 目标主机
            dsthost = "10.168.1.42"
            // 目标目录
            dstroot = "/opt/dstroot"
            // 凭证ID 
            credentials = 'root10.168.1.42'
            // Java 运行参数
            java_opts = "-Xms256m -Xmx512m"
        }
        options {
            // 不允许同时执行流水线, 防止同时访问共享资源等
            disableConcurrentBuilds()
            // 显示具体的构建流程时间戳
            timestamps()
        }
        triggers {
            GenericTrigger(
                genericVariables: [
                  [key: 'ref', value: '$.ref']
                ],
                // 钩子密钥
                token: "abcd" ,
                causeString: ' Triggered on $ref' ,
                printContributedVariables: true,
                printPostContent: true,
                regexpFilterText: '$ref',
                regexpFilterExpression: '^(refs/heads/dev)$'
            )
        }
    
    
    
        stages{
            stage('Prepare') {
                steps{
                    echo "1. Prepare Stage"
                    //git branch: 'dev', url: 'http://chenkai:chenkai@10.168.1.21:3000/dtseaci/hello.git'
                    checkout scm
                    //sh "echo $ref"
                    //sh "printenv"
                    //script {
                        //sh 'ls -l'
                    //}
                }
            }
            stage('Maven'){
                steps{
                    echo "2. Maven Stage"
                    script{
                        //sh "cat /etc/os-release"
                        sh "/opt/maven/bin/mvn package"
                    }
                }
            }
            stage('Deploy'){
                steps{
                    echo "3. Deploy Stage"
                    script{
                        def _pom = readMavenPom file: 'pom.xml'
                        _version = _pom.getVersion()
                        _artifactId = _pom.getArtifactId()
                        sh "sed -i 's/<API_NAME>/${_artifactId}-${_version}/' Launch"
                        sh "sed -i 's/<JAVA_OPTS>/${java_opts}/' Launch"
                        //sh "scp hello-0.0.1-SNAPSHOT.jar"
                        withCredentials([sshUserPrivateKey(credentialsId: credentials,keyFileVariable: '_keyfile',usernameVariable:'_uname')]) {
                            def remote = [:]
                            remote.name = "dest"
                            remote.host = dsthost
                            remote.allowAnyHosts = true
                            remote.user = _uname
                            remote.identityFile = _keyfile
                            sshCommand remote: remote, command: "mkdir -p ${dstroot}"
                            sshPut remote: remote, from: 'Launch', into: "${dstroot}"
                            sshPut remote: remote, from: "target/${_artifactId}-${_version}.jar", into: "${dstroot}"
                            sshCommand remote: remote, command: "mv -f ${dstroot}/Launch ${dstroot}/Launch.sh"
                            sshCommand remote: remote, command: "chmod +x ${dstroot}/Launch.sh"
                            sshCommand remote: remote, command: "cd ${dstroot} && ./Launch.sh restart"
                            
                        }
                    }   
                }
            }
    
        }
    }
    
    • Launch
    #!/bin/sh
    CWD=$(cd $(dirname $0); pwd)
    
    
    API_NAME=<API_NAME>
    JAR_NAME=$CWD/$API_NAME\.jar
    #PID  代表是PID文件
    PID=$CWD/$API_NAME\.pid
    
    #使用说明,用来提示输入参数
    usage() {
        echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
        exit 1
    }
    
    #检查程序是否在运行
    is_exist(){
      pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
      #如果不存在返回1,存在返回0     
      if [ -z "${pid}" ]; then
       return 1
      else
        return 0
      fi
    }
    
    #启动方法
    start(){
      is_exist
      if [ $? -eq "0" ]; then 
        echo ">>> ${JAR_NAME} is already running PID=${pid} <<<" 
      else 
        nohup java <JAVA_OPTS> -jar $JAR_NAME >/dev/null 2>&1 &
        echo $! > $PID
        echo ">>> start $JAR_NAME successed PID=$! <<<" 
       fi
      }
    
    #停止方法
    stop(){
      #is_exist
      pidf=$(cat $PID)
      #echo "$pidf"  
      echo ">>> api PID = $pidf begin kill $pidf <<<"
      kill $pidf
      rm -rf $PID
      sleep 2
      is_exist
      if [ $? -eq "0" ]; then 
        echo ">>> api 2 PID = $pid begin kill -9 $pid  <<<"
        kill -9  $pid
        sleep 2
        echo ">>> $JAR_NAME process stopped <<<"  
      else
        echo ">>> ${JAR_NAME} is not running <<<"
      fi  
    }
    
    #输出运行状态
    status(){
      is_exist
      if [ $? -eq "0" ]; then
        echo ">>> ${JAR_NAME} is running PID is ${pid} <<<"
      else
        echo ">>> ${JAR_NAME} is not running <<<"
      fi
    }
    
    #重启
    restart(){
      stop
      start
    }
    
    #根据输入参数,选择执行对应方法,不输入则执行使用说明
    case "$1" in
      "start")
        start
        ;;
      "stop")
        stop
        ;;
      "status")
        status
        ;;
      "restart")
        restart
        ;;
      *)
        usage
        ;;
    esac
    exit 0
    
    

    相关文章

      网友评论

          本文标题:Jenkins Pipeline + Gogs 实现 Sprin

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