Jenkins最佳实践

1 利用jenkins的并行构建
如果服务器有多个CPU或多个核,则可以使用jenkins的并行构建提高构建效率,需要使用比较新的Declarative Pipeline语法,它的结构是这样的:

pipeline {
  agent 'dev'
  stages {
    stage('Non-Parallel Stage') {
      steps {
        echo 'This stage will be executed first.'
      }
    }
    stage('Parallel Stage') {
      parallel {
        stage('Branch A') {
          steps {
            echo "On Branch A"
          }
        }
        stage('Branch B') {
          steps {
            echo "On Branch B"
          }
        }
      }
    }
  }
}

这里的Branch A和Branch B执行的时候会并行执行

2 gradle的并行构建
另外一种并行构建方法是利用gradle的并行构建功能,只要在properties文件中配置org.gradle.parallel=true即可开启。如果项目中有多个互不依赖的子项目,则构建的时候,这些子项目会同时进行构建。

3 简化gradle构建步骤
使用gradle构建微服务系统时,通常会用到application插件,但是这个插件中的步骤并不是全都用到,比如打包过程等,可以在脚本中将这些步骤排除掉:

startScripts.enabled = false
test.enabled = false
bootDistTar.enabled = false
bootDistZip.enabled = false
distTar.enabled = false
distZip.enabled = false

4 使用自定义的基础镜像
构建java应用的docker镜像时,我们使用openjdk:8u171-alpine做基础镜像。但是这个基础镜像的时区并不是东八区,我们需要在Dockerfile中添加以下两行:

COPY localtime /etc/localtime
RUN echo 'Asia/Shanghai' > /etc/timezone

微服务系统中通常会构建多个docker镜像,每个Dockerfile都加这两行有些重复。
我们使用openjdk:8u171-alpine构建了一个自定义的基础镜像,然后其它的应用再基于这个自定义的基础镜像进一步构建镜像,解决了配置重复的问题。

5 使用docker-compose简化脚本
构建镜像以及启动docker的时候,通常会传很多参数,例如docker的IP和端口、docker的名字、docker所在网络、挂载卷等,每个应用的参数都不一样,
如果把这些构建参数全都写在jenkins的pipeline脚本中,会让脚本变得很繁琐。
使用docker-compose可以将所有的构建参数全都写在一个yml格式的配置文件中,构建镜像和启动docker的时候,只要引用这个配置文件即可。
这里有一个配置示例:

  portal:
    image: $DOCKER_REGISTRY/portal
    container_name: portal
    networks:
      mynetwork:
        ipv4_address: 172.18.1.100
    ports:
     - "8180:80"
    environment:
      API_URL: $API_URL

  

这个示例可以启动一个名叫portal的docker,它所基于的镜像是$DOCKER_REGISTRY/portal,运行的docker名字叫portal,使用网络名叫mynetwork,docker的IP是172.18.1.100,端口映射是80映射到8180,系统的环境变量API_URL传递到了docker内部的环境变量。

6 通过环境变量脚本区分构建环境
系统编译、部署所用到的环境有多套,有内网的测试服务器环境,还有公网的阿里云服务器环境,在不同服务器上构建所传的参数是不一样的。
我们根据环境名称创建了几个不同的环境变量文件ci.env、test.env等,构建之前先执行这些env文件激活环境变量。
文件示例如下:

export DOCKER_REGISTRY=registry.cn-shanghai.aliyuncs.com
export SPRING_PROFILES_ACTIVE=ci
export NGINX_PORT=1443
export API_URL=https://192.168.1.200:$NGINX_PORT

  

其中,DOCKER_REGISTRY是阿里云镜像服务器的url,办公室内网访问的阿里云镜像服务器url和阿里云服务器直接访问镜像服务器url是不一样的,所以这里针对url进行了区分;
SPRING_PROFILES_ACTIVE是springboot所使用的profiles配置;
NGINX_PORT是nginx的端口,办公室内网服务器通常会起多套系统,因此每个系统的nginx端口都不一样,而阿里云上每台服务器只跑一个系统,为了方便,端口都使用443端口;
API_URL则是用户访问web的使用所需要请求的url。

7 Declarative Pipeline脚本的其它功能
在jenkins中创建参数化的任务时,如果参数很多,需要一个一个手动配,非常繁琐。
Declarative Pipeline脚本增加了parameters和triggers,可以把参数及触发条件直接配置在脚本中,这样就不需要在任务界面手动配置参数和触发条件了。

  parameters {
    choice(name: 'node', description: '运行结点', choices: ['dev', 'test01', 'test02', 'test03', 'ci'])
    choice(name: 'profile', description: 'profile', choices: ['ci', 'test'])
    choice(name: 'installModules', description: '编译portal的时候是否完整安装modules', choices: ['false', 'true'])
  }
  
  triggers {
    cron('H 0 * * *')
  }

 参考资料:
https://testerhome.com/topics/10033
https://jenkins.io/doc/book/pipeline/syntax/

 

posted @ 2018-12-25 17:09  lasdaybg  阅读(1266)  评论(0编辑  收藏  举报