从零打造自己的CI/CD系统|编译产物分发

2020-07-02 21:52:46 浏览数 (1)

从零打造自己的CI/CD系统|编译产物分发

不同语言的编译结果是不一样的,Java的使用mvn编译之后的产物是jartar包,PHP采用composer编译后的产物非压缩包,nodejs采用npm编译后的产物也是非压缩包,这个时候每个公司的同步场景可能不一样,有的是把编译后的产物上传到工件库里,在CD的过程中进行拉的动作,这样的实现是不同的环境使用同一份编译后的产出,避免因环境不同而造成的代码不同偏差。下面我们来聊聊应用编译后产物的同步机制。

常见的同步机制

•编译一次,上传工件库,然后各环境部署的时候都是从工件库里获取•在中控机(发布机)上进行编译动作,然后进行分发•在RS上进行编译动作,然后把编译后的产物移动到指定的目录

工件库分发

大家看到这个,其实会想到Docker, 因为这个工作机制和Docker的镜像是类似的,好处就是减少时间因环境环境变更(dev--->test--->prod)确保都是同一份源代码编译出的产物,减少因为环境变更过程中有人再次提交代码到上线分支里去,不过,真的要实现上述所说的场景还是有点难度的,首先选型的工件库要支持多语言的存储,再则就是应用对应的gitlab的仓库名称尽可能要和项目的名称保持一致,或有一个约定,这样在后续CD分发的过程中,调用工件库获取对应的编译后产物才能做到一对一(当然也可以入库,每次读取最新的)。

其实也有不好的点,那就是CI这一部分没有做好的话,用这种方式其实是自带枷锁,大家可以自己思考下~

发布机分发

在发布机器上编译一次,然后进行分发操作,这种方式也有自己的优缺点

优点

•不用每台RS上都安装编译环境(mvn, composer, npm)等•同样的工作只需做一次(发布机上做一次编译即可)•分发之前不会产生额外的网络消耗

缺点

•每次都是拉最新的代码进行编译,如果分支模型没有一个很好的约束,那将是一场灾难

RS机器上分别操作

在机器上直接进行编译动作,这个在有几台机器的情况下这么做还凑合,机器也业务量上来的情况下,再这么搞,真的是挖坑了,原因是有两点:

•在RS机器上进行编译,首先需要环境,你需要在每台机器上都要安装对应的环境•在业务机器上,我个人是很反感安装和当前业务无关的应用的(监控,日志组件这些不算)

分发注意事项

类似php, python等语言的编译产物,一定要排除.git目录

相信大家在网上也会经常看到很多文章提到,通过.git目录还原源代码的操作,如果没有做防范,大家打开你的站点,https://example.xxx/.git/config, 那真的是呵呵了,当然了,java的话,那就不需要这么做了,视场景来决策要采取的动作。

过滤不必要的目录

在我们写代码或使用Docker的时候,我们会用到.gitignore.dockerignore两个文件来排除掉我们不想上传到仓库或打到镜像里的文件或目录,那么在CI/CD的过程中,我们同样需要去主动排除一些非runtime依赖的目录和文件。

使用Ansible实现编译产物分发

这里我们采用的方式是上面说的第二种方式,在发布机器上进行编译,然后分发

逻辑大概讲解

•区分环境,然后根据上篇文档描述,创建本地编译后的产物的存放目录•然后同步本地目录内的产物到远程机器上去,部署过程rolling update

实现代码如下

总结

应用分发也是一门大学问,在海量机器 顶级流量的场景下,分发一次的时间成本还是蛮高的,所以很多公司自研了内部分发平台,大家可以去搜索下p2p传输看看,之前百度是有做过类似的公开演进,十万 机器的极速分发,感兴趣的小伙伴可以去搜索下看看。

0 人点赞