云效、流水线、Gradle缓存问题、build.gradle配置snapshot

news/2025/3/13 17:20:07/

云效

大部分研发者们或许都听说过阿里云云效,甚至有不少使用经验;但是几乎很少有人会关注过云效的(子)域名:
在这里插入图片描述
如上图,云效的定位(愿景)就是为研发者们提供一站式的团队协作、效能提升的DevOps工具栈。云效包括如下几个产品,每个产品都在持续优化(新增功能、优化交互体验、修复Bug等)中,且会新增产品:

  • 项目协作:Projex,集成项目、迭代、需求、任务、Bug等管理功能,其他功能包括:里程碑、风险、度量、工作项、工时、路线图等;
  • 效能洞察:Insight,没用过;
  • 钉钉文档:DingTalk Docs,没用过;
  • 知识库:Thoughts,没用过;
  • 代码管理:Codeup,类似于GitHub,GitLab等;
  • 流水线:Flow,类似于Jenkins构建;
  • 制品仓库:Packages,对Java开发者而言,类似于Nexus仓库;
  • 应用交付:AppStack,流水线的进阶+高级版,鄙人后面会再写一篇AppStack使用经验文章;
  • 测试管理:Testhub,测试用例库,用于管理Test Case。

关于DevOps,推荐一本书《DevOps实践指南》,另外我写了一系列(共三篇)读书笔记,供参考阅读:

  • 《DevOps实践指南》笔记-Part 1
  • 《DevOps实践指南》笔记-Part 2
  • 《DevOps实践指南》笔记-Part 3

流水线

流水线隶属于云效的一个子产品,但是有一个独立的子域名flow.aliyun.com;也就是说,可直接打开流水线。另外流水线是对代码进行构建,也可从代码管理(Codeup,也有自己的独立子域名)里,对某一个代码仓库Repository,打开若干流水线。
在这里插入图片描述
一个Git repository可以创建若干个流水线:
在这里插入图片描述
选择某个流水线,不出意料,路径是pipelines,和Jenkins Pipelines理念一致:
在这里插入图片描述
如上图,功能稍微摸索一下就明白。流水线运行不一定会产生部署动作,云效留出两个Tab标签页,点进去也能发现运行历史个数大于部署历史个数。

另外点击页面的右上角,见名知意:
在这里插入图片描述
比较核心的操作在于上图左侧的【编辑】,默认进入流程配置标签页:
在这里插入图片描述
在【基本信息】里可设置【环境、标签、分组】,这样就方便在流水线子域名里对若干个不同的Git Repository进行统一管理:
在这里插入图片描述
在【触发设置】里可设置自动构建的触发逻辑:
在这里插入图片描述
在【变量和缓存】里可设置构建时需要使用的变量;当然也可以写死,比如说Harbor镜像仓库域名。但是如果小概率事件发生,比如Harbor域名需要变更,则需要更新域名。因此统一在流水线里设置全局的变量,然后所有的流水线都可以使用此变量。
在这里插入图片描述
终于要来到本文的重点,几流水线构建【缓存】,右上角有【清理缓存】功能可用于删除Gradle缓存
在这里插入图片描述
什么场景下需要删除Gradle缓存

Java开发里,经常遇到的场景,比如A应用依赖于B应用(通过OpenFeign,直接依赖于B应用提供的Client)或依赖于C框架。如果B或C应用使用正式版(比如,1.2,或1.1-release,或1.0-RELEASE),而且B或C应用发生变更,则C应用在构建时,需要删除本地缓存,否则依赖旧的版本,则会出现意料之外的问题。

当然云效流水线还有其他很多需要了解和调研的知识点。

Gradle缓存问题

在这里插入图片描述
如上图,第4次构建于3月6日(此次构建之前已经进入到流水线编辑页面,执行删除过Gradle缓存),但是当时没有注意到耗时仅47秒(删除过缓存,构建耗时绝对不可能只要几十秒)。

3.7日才发现服务异常:
在这里插入图片描述
也就是说,流水线里清除Gradle缓存,重新运行:

  1. 速度很快;
  2. 缓存没有被清理(应用运行失败,使用旧版本的依赖)

具体原因,还在钉钉群咨询阿里云云效支持。

排查

排查(试图解决问题)的尝试包括:

  • 重试法宝,如上上图的第5次构建,镜像版本还是有问题;
  • 修改流水线配置,再次运行流水线,镜像版本还是有问题;
    在这里插入图片描述
  • 不开启缓存,理论上是第2行的Gradle缓存/root/.gradle/caches引发的问题,为了防止其他缓存(如/root/.cache)可能造成构建的镜像版本不对(主要还是对流水线的底层原理不太清楚),将其他缓存也关闭。再次运行流水线,镜像版本还是有问题;
    在这里插入图片描述

解决方法

使用云效AppStack构建出一个镜像,如下图【第一次】执行耗时21分钟,比较正常,通过Helm使用该镜像版本后,没有问题:
在这里插入图片描述

但是

AppStack实际上还是基于流水线,增加统一的多环境管理能力,以及多分支构建和部署能力(比较适合于公有云+私有化场景)。

这一次AppStack构建镜像版本成功,不代表后面不会出现类似问题。

解决方案

上面使用AppStack确实可以解决问题,但是因为AppStack基于流水线,终究还是一个临时的解决方法。

分析

流水线和AppStack的构建,关于缓存配置,肯定是需要开启的,要不然构建会很慢,无法形成持续构建(CB,Continuous Build),不满足DevOps理念。

另一方面,某些被其他应用依赖的应用,比如被调用方,或框架组件,会不定期需要更新或调整逻辑。如果每次有更新,在流水线(或AppStack)里都需要手动删除缓存

  • 非常麻烦
  • 容易忘记

思路

联想到Maven版本管理经验,有两类

  • RELEASE:可小写为release,也可省略,代表正式版本;
  • SNAPSHOT:可小写为snapshot,代表快照版本。

同样地,Nexus仓库中也分为release和snapshot。主要区别在于,本地获取这些依赖的机制有所不同。

假设应用依赖一个库的正式版本,构建时构建工具会先在本次仓库中查找是否已经有这个依赖库Jar包,没有的话才会去远程仓库中去拉取。而快照方式,则是默认每次都去远程仓库检查是否有更新版本的Jar包,有则下载缓存到本地仓库,并使用最新版本的依赖。

在团队协作中,A应用依赖于B应用提供的Jar。如果以release方式发布到公司内部Nexus仓库(或publish到云效制品仓库)的话,则A应用不能获取到接口的更新。

解决方法:

  • 手动去本地仓库删除这个Jar(对应于流水线构建前的手动删除缓存),然后重新下载;
  • 强制要求B应用每次更改Jar包时都发布一个新的版本,当然A应用也需要同步升级版本号。

无论哪种方式,都会显得很低效。此时就需要使用快照方式去发布版本。

使用snapshot方式,每次构建时去内部远程仓库检查是否有更新版本的snapshot快照版本,有则下载;但是这样会显得低效。

因此Maven提供以下机制控制检查快照版本的时间间隔,包括:

  • always:每次都去远程仓库查看是否有更新;
  • daily:只在当天第一次构建时检查是否有更新,其它时候则不会检查,默认配置值;
  • interval:设置一个分钟为单位的间隔时间,在这个间隔时间内只会去远程仓库中检查一次;
  • never:不会去远程仓库中查找,和正式版本行为一样。

pom.xml配置示例:

<repositories><repository><id>myRepository</id><url>http</url><snapshots><enabled>true</enabled><updatePolicy>daily</updatePolicy></snapshots></repository>
</repositories>

Gradle

当前这个Git Repository使用Gradle构建工具。类似地,在build.gradle配置文件里,可设置本地缓存的更新策略:

dependencies {// api "com.tesla:tesla-security:1.1"implementation(group: 'com.tesla', name: 'tesla-security', version: '1.1-snapshot', changing: true)
}

总结:在开发模式下,可频繁地发布SNAPSHOT版本,以便让其它项目能实时使用到最新的功能做联调;当版本趋于稳定时,再发布一个正式版本,供正式使用。当然在做正式发布时,也要确保当前项目的依赖项中不包含对任何SNAPSHOT版本的依赖,保证正式版本的稳定性;否则可能不能发布成功(即校验是否含有SNAPSHOT依赖)。

值得注意的是,很多文章,包括ChatGPT都提到如下配置:

configurations.all {// check for updates every buildresolutionStrategy.cacheChangingModulesFor 0,'seconds'
}

经过验证,不增加如上配置,也可以拉取到最新的snapshot版本。

这也是Maven的推荐规范和做法。

最后

当然,很多公司一般也允许在生产(正式)环境里使用SNAPSHOT版本的依赖;毕竟团队协作复杂后,关联方都需要同步升级版本也比较麻烦。建议根据公司、团队、项目、和业务的具体情况,case by case,按需选择。

参考Maven问题总结。


http://www.ppmy.cn/news/1578836.html

相关文章

vscode自定义背景色

故事背景,vscode默认的是黑色&#xff0c;windows默认的是白色&#xff0c;白色看久了&#xff0c;看黑色看不清楚。以前写C灰色习惯了。需要修改背景色。 自定义背景色 打开 VSCode。 按下 Ctrl , 打开设置。 在搜索栏中输入 workbench.colorCustomizations。 点击 “编辑 i…

数字IC/FPGA校招笔试题解析(一)

数字IC/FPGA校招笔试题解析&#xff08;一&#xff09; 题目1 问题&#xff1a;数字电路设计中&#xff0c;下列哪种手段无法消除竞争冒险现象&#xff1f; 选项&#xff1a; a. 加滤波电容&#xff0c;消除毛刺 b. 增加冗余项消除逻辑冒险 c. 增加选通信号&#xff0c;避开毛…

纯前端全文检索的两种实现方案:ElasticLunr.js 和 libsearch

纯前端全文检索的两种实现方案&#xff1a;ElasticLunr.js 和 libsearch 在前端开发中&#xff0c;实现全文检索功能可以显著提升用户体验&#xff0c;尤其是在处理大量文本数据时。本文将介绍两种流行的纯前端全文检索方案&#xff1a;ElasticLunr.js 和 libsearch。这两种方…

【反无人机目标检测数据集】MIDGARD:关于基于机器学习的微型无人机视觉相对定位的训练数据集

On training datasets for machine learning-based visual relative localization of micro-scale UAVs 关于基于机器学习的微型无人机视觉相对定位的训练数据集 0.论文摘要 摘要——通过利用我们相对微型无人机定位传感器UVDAR&#xff0c;我们生成了一个自动标注的数据集MID…

LeetCodehot 力扣热题100 零钱兑换

详细运行思路 这段代码使用动态规划&#xff08;Dynamic Programming, DP&#xff09;解决最少硬币找零问题。 它的核心思想是&#xff1a; 状态转移方程&#xff1a; dp[i] min(dp[i], dp[i - coins[j]] 1) 表示兑换 i 元最少需要的硬币数&#xff0c;取决于使用 coins[j…

Android app:layout_constraintHorizontal_bias=“0“属性详解

在 Android 的 ConstraintLayout 中&#xff0c;app:layout_constraintHorizontal_bias 是用于控制控件在水平方向上相对约束位置的关键属性。以下是其详细解析&#xff1a; 一、核心作用 该属性用于调整控件在两个水平约束点之间的偏移比例&#xff0c;取值范围为 0.0&#…

基于AI智能算法的无人机城市综合治理

随着人工智能技术的飞速发展&#xff0c;无人机技术与AI的结合正在成为城市治理的新趋势。无人机不仅能够提供城市上空的高清视角&#xff0c;而且通过搭载的智能算法&#xff0c;可以实现自动化的监控、分析和响应&#xff0c;极大地提升了城市管理的效率和智能化水平。 无人机…

react基础语法视图层类组件

react基础语法视图层&类组件 MVVM *区别mvc&mvvm 两者的区别&#xff1a; 数据模型去渲染视图。数据层改了&#xff0c;vue自己会监听到帮我们拿最新的数据去渲染视图&#xff1b;构建数据构建视图&#xff0c;数据驱动的思想。这一套是非常相似的。 视图中的内容改变&…