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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 快速学习不可变构建及如何提升构建效率

开发者学堂课程【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个仓库,减少拉取的时间。

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

源代码管理及软件配置

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

相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。   相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
6月前
|
资源调度 前端开发 JavaScript
构建高效前端项目:现代包管理器与模块化的深度解析
【2月更文挑战第21天】 在当今快速演变的前端开发领域,高效的项目管理和代码组织已成为成功交付复杂Web应用的关键。本文将深入探讨现代前端包管理器如npm, yarn和pnpm的工作原理,以及它们如何与模块化编程实践(例如CommonJS、ES6模块)协同工作以优化开发流程。我们将剖析这些工具的内部机制,了解它们如何解决依赖冲突,提高安装速度,并保证项目的健壮性。同时,本文还将介绍模块化编程的最佳实践,包括代码拆分、重用和版本控制,帮助开发者构建可维护且性能卓越的前端项目。
|
11天前
|
监控 安全 测试技术
构建高效的精准测试平台:设计与实现指南
在软件开发过程中,精准测试是确保产品质量和性能的关键环节。一个精准的测试平台能够自动化测试流程,提高测试效率,缩短测试周期,并提供准确的测试结果。本文将分享如何设计和实现一个精准测试平台,从需求分析到技术选型,再到具体的实现步骤。
47 1
|
30天前
|
前端开发 JavaScript API
Gulp:高效构建流程中的流式处理利器
【10月更文挑战第13天】Gulp:高效构建流程中的流式处理利器
33 0
|
2月前
|
存储 前端开发 API
探索后端技术:构建高效系统的关键路径
在数字化时代,后端技术作为软件架构的核心支柱,承载着处理数据逻辑、服务前端应用和确保系统稳定运行的重要职责。本文将深入浅出地介绍后端技术的基础知识、关键组件以及在实际项目中的应用实践,旨在为开发者提供一条清晰的学习路径,助力其构建高效、可扩展的后端系统。通过案例分析和最佳实践的分享,我们将揭示如何运用现代后端技术解决复杂业务问题,提升用户体验,并推动企业的数字化转型进程。
|
3月前
|
API 项目管理 开发者
构建高效的技术文档策略
【8月更文挑战第7天】在技术快速发展的今天,有效的文档编写不仅能够加速知识传递,还能促进团队协作和项目管理。本文将探讨如何构建一个高效的技术文档策略,涵盖从规划到实施的各个阶段,旨在帮助读者理解并应用这些原则以提升工作效率和文档质量。
|
4月前
|
监控 Java 测试技术
如何构建高效的自动化测试框架:策略与实践
【7月更文挑战第6天】构建高效的自动化测试框架是一个持续的过程,需要不断迭代和优化。通过遵循设计原则、选择合适的关键技术、并遵循科学的实施步骤,我们可以构建出稳定、可靠、易于维护的自动化测试框架,为软件质量的提升和交付周期的缩短提供有力支持。
|
5月前
|
数据采集 存储 监控
构建高效爬虫系统:设计思路与案例分析
构建高效爬虫系统涉及关键模块如爬虫引擎、链接存储、内容处理器等,以及用户代理池、IP代理池等反反爬策略。评估项目复杂性考虑数据规模、网站结构、反爬虫机制等因素。案例分析展示了电子商务价格比较爬虫的设计,强调了系统模块化、错误处理和合规性的重要性。爬虫技术需要不断进化以应对复杂网络环境的挑战。
125 1
|
6月前
|
监控 测试技术 持续交付
构建高效持续集成系统的策略与实践
【5月更文挑战第28天】 在快速迭代的软件开发过程中,持续集成(CI)系统是确保代码质量和加速交付的关键。本文将探讨构建一个高效、可靠的CI系统的关键策略,并通过实际案例分析如何实现这些策略。我们将讨论自动化测试、容器化部署、监控和日志记录等主题,以及它们如何共同作用以提升开发流程的效率和稳定性。通过实施这些策略,团队可以显著减少集成问题,并缩短从开发到部署的时间。
94 2
|
5月前
|
Linux 测试技术 iOS开发
Meson:现代的构建系统
Meson:现代的构建系统
166 0
|
6月前
|
存储 缓存 安全
【C/C++ 项目优化实战】 分享几种基础且高效的策略优化和提升代码性能
【C/C++ 项目优化实战】 分享几种基础且高效的策略优化和提升代码性能
336 0