不可变构建及如何提升构建效率 | 学习笔记

简介: 快速学习不可变构建及如何提升构建效率

开发者学堂课程【ALPD 云架构师系列:云原生 DevOps 36计-阿里云云效出品不可变构建及如何提升构建效率】学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/772/detail/13498


不可变构建如何提升构建效率


主要内容

一.终态:提供稳定、可预期的系统

二.可预期的系统,始于预期的制品产物

三.几个常见的构建问题

四.不可变构建

五.构建的效率问题

六.提高构建效率的实践建议


一.终态:提供稳定、可预期的系统

软件交互是面向终态的,终态提供稳定、可预期的系统。服务提供了相应的请求,给相应预期的返回。可预期的系统,需要确定的环境软件制品,比如容器镜像。在市场环境部署,环境是确定的,部署的东西是确定的,否则系统不知道是怎样的。

东西分发出去需要确保版本的一致性,否则影响整个软件交付。


二、可预期的系统,始于预期的制品产物

image.png

image.png

代码、编出来的包、镜像都属于制品,软件制品构建的容器镜像,将软件制品当作容器镜像。传统的构建过程里代码及其代码依赖,依赖 so 文件。在确定的环境里确定构建脚本,自己构建动作伸展出软件制品,是非常常见的操作。本地结合构建产生二进制文件,二进制文件是软件制品。

软件制品必须包含:

有确定的格式,容器镜像或 tar 包能够确定格式。

有唯一的版本,构建出来的版本都不一样,版本与代码的版本或依赖的版本、环境版本、构建脚本的版本是强相关的,软件制品有版本。

能够追溯到源码,可以知道从哪制出,如果制品很难溯源产生很多制品管理问题。比如在某台生产环境里,二进制文件出现问题,不知道什么原因导致。本身构建很乱,谁都可以直接替代生产环境。

能够追溯到生产和消费过程,制品通过哪些阶段有哪些活动最后产生出来可以溯源。可以知道制品被用在哪些环境,被谁用,制品有标签,知道是什么有什么样的特性。

构建并不陌生,每天在电脑里执行很多次。


三.几个常见的构建问题

1.应用的代码仓库没有Makefile/package.json/…,怎样构建,是初学者拿到代码第一个问题,拿到代码构建不知道怎样构建出来。

2.为什么make build执行成功,但制品缺少了几个依赖的组件,成功了但少了一些东西,怎么来的、在哪定义的不知道。

3.同一份代码,上周可以编过,但今天报编译错误。

电脑上可以编译成功,但服务器上失败。换个环境编辑失败,不知道为什么失败。

4.包在测试环境上运行是正常的,但到生产环境出错。编出来,运行的环境不同也不一样。由于运行环境、构建环境不同依赖的版本导致遇到类似问题。

问题的根源,构建是可变的。当构建可变时带来一系列问题。


四.不可变构建

1.不可变构建含义

image.png

相同代码相同依赖在同样构建环境、同样的构建脚本的描述下出来的软件制品是相同的。所有东西保证一致性,前三者一样,产出的制品一样,不同时间构建也是一样的。不可变构建基础理解。有的人做不到不可变构建,代码是一样的但构建环境不同,依赖看上去是一样的不同时间点拿到是不一样的。用 snapshot 的 Java 程序,snapshot 永远的资源版本,不知道今天与明天是否为一个版本。不可变构建并不是绿色软件制品相同,而是如何确保蓝色条件相同。

2.相同代码、相同依赖

image.png

依赖分为两种源码的依赖、组件制品的依赖。go 依赖源码Java 依赖 class 架包,每一个依赖有明确版本要求,依赖的什么,什么版本。源码加制品版本能够唯一描述此依赖,如果源码加依赖的版本可变,依赖可变,做不到依赖相同的概念。

常见依赖

·go.mod

.package.json &

package-lock.json

.pom.xml

.requirements.txt

package.json本身定义可变,里面版本比此版本新,但一般有 package-lock,固定起来。两个加起来为不可变的。

pom 里有xml版本认为是确定版本。Requirements 在 Demo 示例代码里 requirements.txt 没有,依赖是可变的,依赖没有做到依赖项 requirements+特定版本,没有版本,可能今天没问题,过一段时间有问题。隔一周时间构建发现有内存的 bug,在构建前一天提交 bug,看源码提交发现问题。有时 library 兼容性出现问题,可对照构建的依赖文件,依赖文件首先确定依赖的哪个代码、代码具体版本是什么、依赖的组件、依赖的 library具体的版本是什么。依赖文件没有明确的表达,构建是可变的,意味着产生一个不符合预期的最终产物,有可能带来系统风险,在安全方面需要考虑的问题。

3.相同的构建环境

image.png

找到相同的构建环境,自己的电脑也不能保证昨天与今天是相同的,可能系统升级。构建环境本身需要描述像应用的运行环境需要描述一样,构建环境描述的方式一样,通过 Dockerfile 描述。应用在怎样环境下构建、构建环境里有哪些组件、组件版本是什么都可以描述清楚。

安装一个包,包的版本是否是确定的还是可变的。不同时候构建不一样,也是一个风险。构建环境与运行环境一样通过 Dockerfile 描述。构建环境的 Dockerfile 是否是运行环境的 Dockerfile,Demo 用同一个 Dockerfile 为了简单,不需要找工具链解决,Dockerfile 又做构建又做运行。如果研究层次发现 Dockerfile 比较大几百兆,构建一层占很大部门,想瘦身分开是很简单的方式,构建时引入许多不必要的依赖,开发库、工具链带来了风险。有兴趣可将文件修改,分为两个。一个是构建环境,应该包含哪些依赖环境、依赖包。另一个运行环境,哪些是必须的,哪些是不必要。此方式构建该如何写,感兴趣可尝试。

4相同构建脚本

image.jpeg

有三块,一是确定构建依赖,构建脚本依赖构建环境。构建依赖是 go.mod 文件,依赖的模块,对应的版本是非常明确的版本。第二点包含构建、运行。构建环境不唯一,没有用确定的版本,永远用最新的不同时间不一样。golong 版本不同,是1.15还是1.14.8不确定,是不好的时间。

保证标准化,交付什么、交付的形态、交付并且部署运维。

保证预期系统日期一致,需要可预期构建制品,必须从三个角度不可变构建产生一致的软件制品。软件的准确性比做得更快更重要,如果做的不准确不一致,经常变来变去,版本不可控,所有的东西浪费。做好准确性单纯从构建角度考虑构建的效率。


五.构建的效率问题:积少成多

100名工程师,平均每人每天构建10次,每次1分钟,每天共耗时16小时非常大的数字。影响工程效率大的因素是构建太慢,构建影响的东西很多。


六.提升构建效率提升的实践建议

1.基本原则:构建的准确性>构建的效率

无论什么构建效率的时段一定保证准确性,构建的准确性永远大于构建的效率,在保证准确性的前提下提升构建效率。

2.实践建议:

.应用瘦身,减少应用的依赖项

做任何开发性之前考虑应用依赖情况,依赖是否太大、依赖是否太多东西、有些依赖是否需要、基础镜像是否可以做更小。

.分层构建,复用底层的构建结果

很大的系统依赖10个组件,每次系统依赖都要将10个代码拉下来,重新码构建,整个时间耗费很大。有多个层次将底层的先构建完成后能被上层复用,构建效率增量。

.构建缓存,避免重复拉取依赖和重复构建

.网络优化,保证代码、构建机器和制品库之间的低网络延时

很多人构建问题都是网络问题,代码构建机器、依赖的制品库 APM 的源与自己之间的网络链太大。首先保证低网络延时,另一点代码与构建机器是否为同一个网络域里。代码与构建机器不在同一个网络域里,之间的延时不会太短,整个机器网络路由长。

.仓库镜像,减少拉取依赖项的时间

自己可以补做镜像,简单仓库很多工具做,有镜像仓库极大减少拉取依赖的时间,投资非常划算。国内有很多镜像仓库,由于网络影响、防火墙,时间停顿久,团队建了3个仓库,减少拉取的时间。

提升构建效率提升的实践建议不是针对某个领域而是所有领域都要考虑。构建从哪里来,最终要找到源头,保证制品、产物一致性必须保证代码版本一致性、依赖的一致性、环境的一致性、构建脚本的一致性,日常生活中都由源代码管理。

源代码管理及软件配置

以代码为中心的交付过程,一切从源代码开始

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
Java 分布式数据库 数据库
软件各种系统架构图
原文:软件各种系统架构图 https://blog.csdn.net/everythingss/article/details/78749247     该技术架构图是本人根据多年企业技术架构经验而制定,是企业技术的总架构图,希望对CTO们有所借鉴。
8517 0
|
12月前
|
运维 监控 安全
天财商龙:云上卓越架构治理实践
天财商龙成立于1998年,专注于为餐饮企业提供信息化解决方案,涵盖点餐、收银、供应链和会员系统等。自2013年起逐步实现业务上云,与阿里云合作至今已十年。通过采用阿里云的WA体系,公司在账号管理、安全保障、监控体系和成本管控等方面进行了全面优化,提升了业务稳定性与安全性,并实现了显著的成本节约。未来,公司将持续探索智能化和全球化发展,进一步提升餐饮行业的数字化水平。
|
网络协议 中间件 网络架构
STUN原理
这篇文章详细介绍了STUN(Session Traversal Utilities for NAT)的原理和应用,解释了STUN如何帮助检测NAT设备的存在并获取其分配的IP地址和端口号,以及如何在两个通信端点之间建立一条可穿越NAT的P2P链接,特别在SD-WAN网络中的应用,并提供了通过Docker搭建STUN服务器的方法。
1547 0
|
监控 Java 持续交付
构建Java微服务架构的CI/CD流程
构建Java微服务架构的CI/CD流程
|
存储 并行计算 测试技术
【CUDA学习笔记】第五篇:内存以及案例解释(附案例代码下载方式)(二)
【CUDA学习笔记】第五篇:内存以及案例解释(附案例代码下载方式)(二)
348 0
【CUDA学习笔记】第五篇:内存以及案例解释(附案例代码下载方式)(二)
|
缓存 Java Spring
《SpringBoot启动流程一》:万字debug梳理SpringBoot如何加载并处理META-INF/spring.factories文件中的信息
1、SpringBoot如何加载并处理spring.factories中的文件? 2、加载出的spring.factories文件中的内容如何排序? 3、多个spring.factories文件内容重复怎么处理?
1408 0
《SpringBoot启动流程一》:万字debug梳理SpringBoot如何加载并处理META-INF/spring.factories文件中的信息
|
监控 安全 Java
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
698 0
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
|
XML 存储 Java
使用Spring Initializr构建Spring Boot详解
本文目录 1. 构建项目 2. 使用Spring Initializr构建项目 3. 导入项目 4. 项目结构分析 5. 项目如何运行的详解 5.1 pom.xml分析 5.2 SpringBootHelloApplication.java分析 5.3 神奇的@SpringBootApplication注解 6. 总结
773 0
使用Spring Initializr构建Spring Boot详解
|
JavaScript Java 应用服务中间件
Maven BOM!拿来吧你
BOM(Bill of Materials)是由Maven提供的功能,它通过定义一整套相互兼容的jar包版本集合,
958 0
Maven BOM!拿来吧你