惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
C
CERT Recently Published Vulnerability Notes
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tenable Blog
O
OpenAI News
NISL@THU
NISL@THU
AI
AI
T
Threat Research - Cisco Blogs
Know Your Adversary
Know Your Adversary
V
Vulnerabilities – Threatpost
Schneier on Security
Schneier on Security
W
WeLiveSecurity
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
S
Secure Thoughts
D
Docker
博客园 - 三生石上(FineUI控件)
T
Troy Hunt's Blog
T
Threatpost
C
Cyber Attacks, Cyber Crime and Cyber Security
Vercel News
Vercel News
H
Hacker News: Front Page
B
Blog
S
SegmentFault 最新的问题
H
Heimdal Security Blog
T
The Blog of Author Tim Ferriss
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
G
GRAHAM CLULEY
AWS News Blog
AWS News Blog
N
News and Events Feed by Topic
L
LINUX DO - 热门话题
小众软件
小众软件
爱范儿
爱范儿
T
The Exploit Database - CXSecurity.com
Hacker News: Ask HN
Hacker News: Ask HN
Recent Announcements
Recent Announcements
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
I
Intezer
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed

czp's blog

Ubuntu 下使用 zsh · HonKit 使用 VNC 来远程管理服务器 · HonKit Linux 下无限试用 JetBrains · HonKit 使用 KMS 激活 Windows · HonKit 为 KVM 中的 Windows 虚拟机启用 VirtIO · HonKit 在 Spring Boot 中处理 MissingKotlinParameterException · HonKit 用 Spring Native 拯救微服务 · HonKit 正确调试 PHP · HonKit Ubuntu 增加最大文件打开数量限制 · HonKit 将 Minecraft 服务端编译到 native · HonKit 用凝聚力购买 P 社游戏 DLC · HonKit 模拟超星网课 Android 客户端 · HonKit 模拟 Bilibili Android 客户端 · HonKit 模拟哔咔 Android 客户端 · HonKit 异步是什么 · HonKit GCP Pub/Sub push 至 IAP 保护的 Endpoint · HonKit 部署 Spring Native 到 GCP App Engine · HonKit Google Cloud Build 运行 DIND · HonKit 在 Google Storage 中部署 SPA · HonKit Terraform 不自动更新 CloudRun service · HonKit Telegram Bot 收不到普通群聊消息的问题 · HonKit 加密货币交易 · HonKit 挖掘以太坊 · HonKit 挖掘门罗币 · HonKit 小明学英语 · HonKit 卖程序的小女孩 · HonKit 一个测试工程师走进一家酒吧 · HonKit 我给你们讲个 TCP 笑话吧! · HonKit 我给你们讲个 UDP 笑话吧! · HonKit 格局打开 · HonKit c 语言常见未定义行为 · HonKit 在 Kotlin 使用 SpaceEngineers Remote API · HonKit Kotlin 协程 · HonKit 在 Spring Boot 中正确注册 Jackson Module · HonKit Spring Boot Jpa 使用 Google Cloud SQL · HonKit Spring Boot 中配置单页应用 · HonKit Spring Boot 无法加载 ClasspathResource 问题 · HonKit 正确打包 Spring Boot 到 war · HonKit czp's blog · HonKit 鸣谢列表 · HonKit 友链 · HonKit
多个 Gradle SubProject 同时编译导致 CI/CD 内存耗尽 · HonKit
2026-04-11 · via czp's blog

撰写此文时的 Gradle 版本: 7.6

Gradle 有一个很好的功能, 它叫做 parallel, 只要在 gradle.properties 文件中开启此功能就能让项目中的多个 sub project 同时编译, 充分利用了所有核心, 大大加快了整体编译速度

org.gradle.parallel=true

但是对 CI/CD 来说这可能产生问题. 大多数情况下 CI 环境可用的资源不会太多, 比如 4GiB 内存差不多是各种免费 CI 的极限了. 而一旦 parallel 起来, 很容易就把 CI 内存用完导致构建失败.

虽然 CI 环境的内存可以通过加钱来调大, 但是公有云上的 CI 不能无限增加配置. 在某些情况下依然会遇上内存不够的问题, 例如说使用 graalvm native image 的时候, 一个 spring native 的 sub project 编译可能就要 8GiB 内存, 四个 sub project 一起编译就要耗费超过 32GiB 内存, 而绝大多数公有云提供的最高规格的 CI 配置也就 32GiB. 如果 sub project 更多, 在公有云上就没有办法并行构建了.

这就产生了矛盾, 又想要并行构建充分利用 CPU, 又不想全部 sub project 都并行而耗尽内存. 想并行, 但只想并行一点点.

其实除了内存耗尽的问题之外, 并行构建还会遇到另一个问题是不能很好地支持会访问外部资源的任务. 例如说一个任务会下载一个互联网文件到固定路径上, 但是这个任务在每个 sub project 中都有, 所以实际执行的时候就是多个任务实例同时下载这个文件, 同时写入到硬盘, 最终结果就是出错.

这里给出一个典型案例: 在一个大 project 中包含了多个 sub project, 每个 sub project 对应一个 GoogleCloud AppEngine service, 且其中一些 service 使用了 graalvm native image. 而 GoogleCloud Build 最大只提供 32GiB 内存.

这个案例的一种解决方案是手动分批执行 gradle 任务. 由于 gradle 在执行任务时会首先检查是否已经有缓存, 如果有缓存就会跳过此任务, 因此渐进式执行不会导致前面的任务被执行多次. 以下述脚本为例

# download gcloud commandline tool before deploy to avoid concurrency downloading
# build all services at first to fully utilize the multi-core cpu
./gradlew default-service:downloadCloudSdk bootJar
# build graalvm native image services one by one(small projects are merged) to reduce memory footage
./gradlew a-service:nativeCompile b:nativeCompile
./gradlew c:nativeCompile d:nativeCompile
# deploy all service
./gradlew appengineDeploy

在 CI 中并不直接执行 appengineDeploy 而是先把该执行的任务都执行好了(把 artifact 都构建出来)再执行 appengineDeploy 把服务一口气部署上去(appengineDeploy 在每个 sub project 里都有, 所以多个 appengineDeploy 任务实例会同时执行).

downloadCloudSdk 这个任务会下载 gcloud 命令行工具到系统上, 这一步是不能并行的, 所以必须让某一个 sub project 的 downloadCloudSdk 任务先执行好(此时只有一个任务在执行), 才能继续执行其他任务. 在下载的过程中, 只有网络资源在被消耗, 所以顺便把所有服务的 jar 包构建出来, 把 CPU 也利用起来.

会导致内存耗尽的就是接下去的构建 native image 的过程. 部分 sub project 构建时可能会耗用超过 10GiB 内存, 所以在脚本中使其两个两个编译, 确保其总内存不会超过 32GiB.

所有需要耗很多内存的任务, 都在上面渐进式一波一波执行好了之后, 最后再启动 appengineDeploy 就一定能成功部署了.