本文主要介绍流水线构建,相关常见问题及错误解决方案。
Java 构建常见问题
Java 构建失败—构建依赖缺失
Flow在Java构建时需要下载settings.xml依赖文件,Flow提供阿里云 Maven 公库作为下载源,如果您的项目涉及自己定义创建的不规则依赖文件,Flow构建会失败,报错信息如下:
为了让Flow可以正常下载您项目构建所依赖的文件完成构建,您可以通过以下三种方式完成配置。
方法一:将依赖包上传至云效制品仓库 packages
如果您项目的代码库根目录没有Maven settings.xml且没有选择企业自定义Maven配置, Flow构建时会为用户自动生成一个settings.xml文件,并且配置云效制品仓库 packages 和阿里云公共代理仓库。因此您可以将自己需要的依赖文件上传至 云效制品仓库 packages,具体操作步骤您可以进入目标制品仓库参考仓库指南。
方法二:将依赖包所在的仓库添加至云效制品仓库 packages 的代理仓库
如果您有私有Maven仓库,又不想把仓库下的依赖文件上传至 云效制品仓库 packages,您可以把原有依赖包所在的仓库地址绑定至云效制品仓库作为代理仓库。Flow在构建时就会从您设置的代理仓库中去拉取依赖文件。
通过进入云效目标制品仓库
,完成代理仓库绑定。建议您在生产库-release 和非生产库-snapshot的代理仓库中均添加您原有的依赖包仓库。方法三:使用企业自定义的 settings.xml 文件
如果您有私有Maven仓库,并且希望Flow在构建时可以直接从您的私有仓库中下载依赖文件,具体配置如下。
在 Flow
自定义Maven配置,并上传settings.xml文件,该企业内所有的Java构建均使用此配置文件。请确保Flow可以通过公网正常访问您的私有仓库,若您的私有仓库有白名单限制配置,请参考云效默认构建集群Flow构建机的 IP 地址配置白名单。
Java 构建缓慢—未设置有效缓存目录
由于Flow流水线执行时,每个任务节点都会创建新的构建环境,构建完后会销毁,为解决流水线运行过程构建依赖反复下载提升整体构建效率的问题,Flow提供了自定义缓存功能。用户可以结合自己使用场景自定义缓存目录,实现流水线任务多次运行缓存共享。
如果您未设置正确的缓存目录,会导致您每次进行Java构建时,即使依赖文件未未更新,也会下载您项目所有的构建依赖。典型现象如下:
即使运行多次后,依然需要耗时很久。
即使运行多次后,依然要下载大量的构建依赖。
如果您的场景包括以下任意一种:
没有使用企业自定义的
settings.xml
(代码库根目录 or 企业自定义Maven配置)。使用了企业自定义的
settings.xml
(代码库根目录 or 企业自定义Maven配置),但settings.xml
中不包含自定义缓存目录节点 <localRepository></localRepository>。
请在流水线编辑 -> 变量和缓存中添加Maven缓存目录/root/.m2
。
缓存目录填写正确且开关开启。
提速效果
增加缓存目录的流水线,只会在第一次构建时下载您所需的依赖文件,后续构建会直接从缓存中加载依赖。
项目的依赖文件越多,缓存的加速效果越明显。
Java 构建缓慢—删除缓存文件
由于 Flow 流水线执行时,每个任务节点都会创建新的构建环境,构建完后会销毁,为解决流水线运行过程中,构建依赖反复下载的问题,提升整体构建效率,Flow 提供了自定义缓存功能。用户可以自定义自己的缓存目录,实现流水线任务多次运行的缓存共享。
当您在构建指令中使用rm -rf
删除了部分缓存文件,会导致您每次构建过程中都会反复下载依赖文件,从而导致构建缓慢。
如果您是担心依赖的 snapshot 包更新后,流水线无法及时拉取,可以修改您的构建指令如下:
mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip -U
在构建指令中添加-U
的作用:
对于release版本,缓存中已经存在,则不会重复下载
对于snapshots版本,不管缓存中是否存在,都会强制刷新,但是刷新并不意味着把jar重新下载一遍。只下载几个比较小的文件,通过这几个小文件确定本地和远程仓库的版本是否一致,再决定是否下载
Java 构建缓慢—自定义 Maven 配置
当您使用了企业自定义的settings.xml
(代码库根目录or企业自定义Maven 配置),且在settings.xml
中 <localRepository></localRepository> 自定义了缓存目录。如果您未将该目录添加至Flow流水线的缓存目录,则会导致您每次进行Java构建时,即使您的依赖文件未发生任何变化,都会下载您项目所有的构建依赖。
您可以通过以下两种方案:
删除您企业自定义的
settings.xml
(代码库根目录 or 企业自定义 Maven 配置)中 <localRepository></localRepository> 节点,使用默认缓存目录,确保流水线编排 -> 变量与缓存中添加Maven缓存目录/root/.m2
。重要缓存目录填写正确且开关开启。
将您企业自定义的
settings.xml
(代码库根目录 or 企业自定义 Maven 配置)中 <localRepository></localRepository> 节点的目录,添加到流水线编排 -> 变量与缓存的缓存目录中。请注意:缓存目录填写正确且开关开启。
Java 构建报错 Could not resovle dependencies for project com.xxx
问题描述:Java构建步骤依赖缺失导致构建失败,典型报错如下。
解决方案:请参考Maven依赖设置检查流水线构建使用的settings.xml是否符合预期,检查settings.xml文件中配置的依赖库是否符合预期,检查依赖库中是否存在目标包文件。
Java 构建缓慢—下载海外依赖
当您使用云效Flow进行 Java构建时,Flow支持通过三种方式设置settings.xml完成Maven配置:
代码库根目录settings.xml文件。
Flow 企业设置 -> Maven设置中上传settings.xml文件。
云效默认的Maven配置settings.xml 文件。
其中,第三种方式,云效默认Maven配置会帮你自动配置连接阿里云企业私有仓库和阿里云公共代理仓库。
若您通过前两种方式使用了企业自定义的settings文件(代码库根目录or企业自定义Maven配置),且settings.xml
中未配置国内的代理仓库,会导致您所有公共的构建依赖都从境外Maven中央库进行下载,从而导致构建缓慢。典型现象如下:
加速方案
优化您的企业settings.xml文件(代码库根目录or企业自定义Maven配置),添加阿里云公共代理仓库,如下:
<mirrors>
<mirror>
<id>mirror</id>
<mirrorOf>central,jcenter</mirrorOf>
<name>aliyunmaven</name>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
提速效果
从阿里云公共代理仓库下载公共依赖,更快更稳定。
Java 构建失败:未拉取到最新依赖包
问题描述:Java构建过程中,未拉取到最新依赖包导致构建失败。
解决方案:
若最新依赖包为新版本号,请检查pom文件中是否更新了相应版本号。
若最新依赖包为老版本号(对已存在的依赖包进行了相同版本的覆盖),解决方法如下。
若依赖包是snapshot版本,可使用
-U
参数强制刷新。构建命令参考如下:mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip -U
若依赖包是release版本,可能原因是老的release依赖包已经被 Flow 缓存,因为版本未发生更新,构建过程中不会重新下载最新依赖包。可参考 缓存设置 清理缓存后重试。
Java构建下载jar包卡住
日志中出现jar包下载不继续往下执行。出现这种情况是由于 jar 包下载失败,首先排查使用的maven源是否为国内镜像源,推荐使用aliyun提供的mave镜像仓库 进行依赖下载加速。
Maven依赖下载报错,提示:上传的包有问题或者找不到
这种情况通常是用户使用二方库依赖导致,排查顺序:首先确认下载依赖使用的私有仓库地址(默认的 settings.xml 文件在 ~/.m2/settings.xml 下),再登录到对应仓库查看该依赖是否存在。
如果依赖存在且使用的是云效提供的私有仓库(repo.rdc.aliyun.com),可以寻求云效答疑帮助。
日志显示:pom.xml文件不存在
请检查代码是否克隆成功,如果克隆成功,请确认代码库根目录存在 pom.xml 文件。
如何在镜像构建中获取Java构建的构建产物
Flow流水线内每个任务节点之间工作区相互独立,需要将Java构建步骤和镜像构建步骤放在同一个任务节点,可选择以下任务。
Gradle 构建报错 ./gradlew: No such file or directory
问题描述:Java构建步骤失败,提示 ./gradlew: No such file or directory
,典型报错如下图。
解决方案:Flow未提供内置Gradle,建议使用GradleWrapper,请检查代码目录下是否存在gradlew文件,若不存在请上传gradlew文件后重试。
Gradle 构建报错 ./gradlew:Permission denied
问题描述:Java构建步骤失败,提示 ./gradlew:Permission denied
,典型报错如下图。
解决方案:该错误原因为gradlew没有执行权限,可以在构建命令中通过chmod +x gradlew
修改gradlew权限后重试。详见下图。
Gradle 构建缓慢或超时失败
问题描述:Java构建步骤Gradle构建缓慢或下载依赖超时失败。
解决方案:
检查Gradle Wrapper是否存在跨境网络等问题,如有,可参考构建环境更换下载源。
检查构建日志是否存在跨境下载依赖情况,如有,可以修改build.gradle文件,将依赖仓库配置为国内代理。如下示例。
buildscript {
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
}
}
}
allprojects {
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
}
}
}
PHP 构建常见问题
PHP 构建报错 requested PHP extension xxx is missing from your system
问题描述:composer install安装失败,提示缺少部分依赖。
解决方案:可以通过类似apt-get install xxx或者yum install xxx 指令安装相关依赖。
PHP 构建 Composer 版本不满足
问题描述:PHP 构建时因 Composer 版本问题导致失败。
解决方案:云效默认 PHP 环境中,提供的 Composer 为 1.8.6。您可通过添加以下指令将默认环境中的 Composer 版本快速升级至 2.1.5。
wget https://rdc-public-software.oss-cn-hangzhou.aliyuncs.com/composer/2.1.5/composer.phar -O /usr/local/bin/composer
Go 构建常见问题
GO 构建报错 not found: xxx 无法访问仓库
问题描述:Go构建步骤报错not found xxx,无法访问仓库,典型报错如下。
解决方案:Go 构建过程中,如果需要通过private registry下载依赖文件,需要在环境中配置相关凭证,可参考设置依赖下载访问凭证配置。
GO 构建下载海外依赖导致构建缓慢
问题描述:从 Github等海外仓库直接下载构建依赖会导致构建缓慢。
解决方案:建议添加以下命令,设置国内代理。
export GOPROXY=https://goproxy.cn
GO 构建报错 no rule to make target build
问题描述:使用make build执行go构建,报错no rule to make target build...。
解决方案:
执行make build需要代码仓库下有makefile文件,请检查您代码中该文件是否存在。
修改流水线中的执行命令,使用本地可以通过的构建命令。
Golang 构建下载依赖卡住
日志中出现依赖下载后不继续执行,可能是由于使用了海外的go镜像源。阿里云提供了官方的Go Module 代理仓库服务,来避免模块拉取缓慢或失败的问题,加速构建。
Go 镜像源访问报错,提示:unrecognized import path
这种情况通常是引文海外Go镜像源存在访问不稳定的情况。建议将镜像源改为使用阿里云提供的 Go 镜像源:https://developer.aliyun.com/mirror。
构建物管理常见问题
构建物上传失败,报错:找不到指定文件或文件夹...
问题描述:代码经过 Flow 构建后,生成了您的构建产物(例如:jar 包),需要先将构建物进行上传,用于后续部署任务(例如:主机部署 ECS)可以获取构建物的下载地址,并通过拉取构建物进行部署。在构建物上传的步骤中,您可以为制品选取一个名称,该名称在流水线后续阶段(比如部署阶段)会被引用到。此外,用户可以指定打包路径,该路径可以为一个文件或文件夹,系统会将其打包为一个压缩包。如果用户想将多个文件或文件夹打包,也可以点击”+”号添加更多的打包路径。
您的打包路径可能填写错误,会导致您的构建物上传失败,典型的报错信息如下:
典型错误场景:Java项目中包含了多个微服务,Flow的构建物上传步骤的打包路径中需要填写构建物的子目录。如下图,微服务spring-boot-mp-demo的构建物子目录在spring-boot-mp-demo/target/
目录下,需要将打包路径修改为spring-boot-mp-demo/target/
。
解决方案:通过Java构建步骤的日志,确认你需要上传的具体路径,修改为正确的上传路径即可。
自有集群构建缓存清理
当你使用自有构建集群,在运行一段时间之后,会产生较多的镜像缓存与依赖缓存需要进行清理。
通过提供的脚本会对以下内容做清理:
镜像缓存
Untaged的镜像,如采用相同的标签进行镜像构建会产生。
自定义环境构建过程中产生的中间镜像,即名称为custom-*的镜像。
一些不再会被使用的步骤镜像。
目录缓存
超过30天未运行过的流水线工作区缓存。
超过7天其他本地缓存。
清理命令如下:
如果需要定期进行缓存清理,建议您将以下命令配置到cronjob中。
docker run -v /var/run/docker.sock:/var/run/docker.sock -v /root/yunxiao:/root/yunxiao registry.cn-beijing.aliyuncs.com/build-steps/cache-cleaner:0.0.3-20230914183240
如果你的企业创建于2023年之前,并且还没有按照私有构建集群Runner升级指南中的提示进行过升级,那么请使用如下的命令进行缓存清理。
docker run -v /var/run/docker.sock:/var/run/docker.sock -v /root/yunxiao/build:/root/yunxiao/build registry.cn-beijing.aliyuncs.com/build-steps/cache-cleaner:0.0.1
本地调试优化
云效为用户提供一定额度的免费构建环境资源,由于构建环境为系统自动生成分配,构建完成会随之销毁。针对构建环境失败的问题,云效提供了本地调试优化工具。
该工具的工作原理,您可以理解为在本机环境中,拉取云效流水线环境的镜像,模拟与Flow上相同的容器环境,并直接在本机中进行命令调试。因此,使用该工具的前提需要在本地安装 Docker。
步骤一:复制调试指令并在本地环境执行
部分流水线任务执行失败后,可以通过本地调试工具查看。由于第一次模拟环境,在拉取构建环境的镜像时候,可能会耗费较长的时间。
步骤二:本地调试
可以通过在失败的流水线步骤中查看当前的环境情况,并在本地环境下模拟调试来解决此问题。如以下示例,流水线任务在“Java 构建”步骤执行失败,使用本地调试工具,进入到该构建的环境目录下调试。
错误:“超时取消”问题排查
在流水线执行中,遇到超时终止的问题,用户可以按照文档进行相应的排查。
NodeJS 构建下载Npm 包卡住
日志中 npm install 后不继续往下执行,可能是由于使用海外 npm 镜像源,使用 cnpm 替换 npm 可以切换到使用 淘宝 NPM 镜像。
其他依赖,如无法下载tar 包
可以考虑将依赖上传到 开始使用OSS,再生成外部下载链接下载。
其他问题
检查是否在脚本中执行了耗时超过一小时的操作。我们建议一个步骤的功能尽可能简单,如果有耗时过长的步骤导致任务超时,请将其拆分为多个步骤且分别在不同任务中进行。
构建常见错误排查
代码下载报错,提示:Clone Failed
这种情况通常是触发流水线的没有代码的访问权限,或者输入源中配置的分支不存在,请检查相关配置。
npm 构建报错,提示:找不到 module
这种情况通常是没有执行 cnpm install, 请检查相关任务的执行命令中是否有 cnpm install,没有请加上。
构建报错,提示:上传文件路径不存在
请检查本地执行构建的构建产物路径和流水线中配置的产物上传路径是否一致。
上传文件的时候试图使用正则匹配,例如: */target/*.jar
上传文件路径不支持正则匹配,需使用 target/ 或者 target/app.jar 这种格式。