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/