持续集成-docker打包自动识别是否需要重新构建maven依赖镜像,再在此基础上构建jar包镜像

  • 引言
  • 打包问题
  • 1.空间浪费
  • 2.发布包增大
  • 问题
  • 1.各个微服务依赖不同
  • 2.依赖更新起来麻烦
  • 方案
  • 方案1(废弃)
  • 方案2 (最终)


引言

在我们公司引入docker、微服务、持续集成,并将其组合成一个整体后,开发测试环境中部署就变得非常简单,页面上点击一下就好。想要部署一整套新的环境,也只需要相应的docker-compose文件或者kubernetes yaml文件即可搭建。这一整套流程,大多数情况下没有问题,但却有两个缺陷在。

打包问题

1.空间浪费

每个微服务本身只有不到1m的代码,但是依赖却有50m以上(spring cloud相关依赖及其它),每次镜像构建即使只有代码变更,也会将依赖给重新打包一遍。很快镜像仓库就满了,只能清理仓库或者扩大仓库空间。

2.发布包增大

上一个问题至少还有治标不治本的方法解决,但是发布包变大了就很麻烦了。如果发布环境在国内那问题不大,几个模块更新镜像200m左右很快就发完了。但是我们公司主要是给国外做系统的,还经常在aws上搭建演示系统,运气好速度能有几百k,运气不好只有十几k,版本更新或者紧急修复只能干耗大量的时间等待。

问题

最开始我们是想通过依赖和代码分离,依赖单独打一层,代码编译文件一层。但是有几个问题。

1.各个微服务依赖不同

微服务本身除了公共的依赖外还有自己的依赖,如果不管三七二十一全部服务用一样的依赖,万一微服务本身需要一个高版本的依赖,其它服务又必须用低版本的依赖,就必须做兼容处理,这就违背了解耦的思想了。

2.依赖更新起来麻烦

如果我需要更新一个微服务的一个依赖,我就需要将这个微服务的依赖镜像重新构建一次,如果我更新了一个公共依赖就需要将所有服务的微服务的依赖镜像全部重新构建一次,麻烦不说,还容易出错,而且既然有了持续集成流程就尽量不要人为的参与构建了。

方案

首先依赖与代码分离的思路肯定是对的,然后只需要打包时能自动识别需不需要构建依赖镜像即可。

方案1(废弃)

首先想到的是直接校验pom文件是否有变更,以此为依据判断是否需要构建依赖镜像。但是我们的公共依赖pom文件是单独的一个代码仓库,意思是我需要判断另一个仓库的pom文件是否有变更。再一个就是,如果只是有人加了个插件、加了个测试时依赖、甚至加了空行空格,我就需要单独将这些情况排除掉,通过脚本的方式是非常麻烦的,所以很快就被我放弃了。

方案2 (最终)

最终方案为通过编译后(已经做过依赖与代码分离),直接获取所有依赖名排序后的字符串形成的数字摘要,然后以此作为镜像的tag去获取依赖镜像,如果能获取到则不打包依赖镜像,如果获取不到就进行依赖镜像的打包。ls lib | sort -f -d | md5sum


Created with Raphaël 2.2.0 开始 打包 查询镜像 构建运行镜像 推送镜像 结束 构建依赖镜像 yes no