Jenkins 打包显示 SUCCESS 但产物不全?日志出现 Killed 的排查与解决(小白版)

你是否遇到过这种离谱情况:

  • Jenkins 构建日志里出现一行:Killed
  • 但流水线最终显示:Finished: SUCCESS
  • 上传到服务器的 dist 目录却文件不全(只剩 logo/favicon,JS/CSS chunk 缺失)
  • 线上访问出现白屏、404、资源加载失败

这篇文章会把这个问题讲清楚,并给出一套"照做就能好"的解决方案。


1. 现象:最典型的日志长什么样?

常见日志片段如下:

text 复制代码
DEPRECATION WARNING: Sass @import rules are deprecated ...
Killed
adding: dist-prod/ ...
SSH: Transferred 1 file(s)
Finished: SUCCESS

注意关键点:

  • Killed 出现了(非常关键)
  • 后面仍然继续打包 zip、继续 SCP 上传
  • 最后还显示 SUCCESS(非常迷惑)

2. 一句话结论:真正的原因是什么?

✅ 这不是 Jenkins 上传的问题

✅ 也不是 zip 打包的问题

❗ 真正原因是:前端构建进程被 Linux 系统强制 Kill 了(多为 OOM 内存不足触发)

于是构建没完成,dist 是半成品,但 Jenkins 还继续走后续步骤,导致你拿到"不完整产物"。


3. 为什么会被 Kill?Killed 到底是什么意思?

3.1 Killed 通常来自 Linux 的 OOM Killer

当系统(或容器)内存紧张时,Linux 内核会选择"杀掉"某些进程来保护系统继续运行,这就是 OOM Killer

被杀的进程往往是:

  • node(前端构建)
  • 或大内存的 java / mvn 子进程

它会直接发 SIGKILL(9),进程"原地消失"。


3.2 为什么你服务器看起来内存很大也会发生?

很多人会说:"我明明 16G 内存啊!"

这里有几个非常常见的误区:

误区 A:Node.js 默认堆内存很小

即使机器 16G,Node 默认最大堆内存也大约只有 1.5~2G 左右(不同版本略有差异)。

大型项目(如 Vue/Vite/Webpack + 大量 SCSS)很容易超过这个阈值,然后崩溃或被 Kill。

误区 B:Jenkins 在 Docker 里跑,容器被限内存

宿主机 16G ≠ Jenkins 容器 16G

容器可能只分配了 2G/4G,Node 在容器里根本"看不到"宿主机内存。

误区 C:内存是"瞬时峰值"问题

面板上看到 64% 内存占用是"平均",但构建时可能瞬间冲到很高,OOM 在一瞬间发生,面板刷新看不到。


4. 为什么 Jenkins 显示 SUCCESS?但产物却不全?

这是本问题最迷惑人的点。

原因通常是:

  • Node 进程被 SIGKILL 干掉
  • Jenkins 脚本没有"失败即退出"
  • Jenkins 继续执行 zip + scp
  • 最终把"半成品 dist"上传了
  • 流水线最后一步返回 0,Jenkins 认为成功

✅ 所以:SUCCESS 只是脚本最后一步成功,并不代表构建过程完整成功。


5. 5 分钟快速定位:确认是不是 OOM

在 Jenkins 服务器上执行(需要 root 或 sudo):

bash 复制代码
dmesg | tail -n 80

或者直接过滤:

bash 复制代码
dmesg | grep -i -E "out of memory|killed process|oom"

如果看到类似:

text 复制代码
Out of memory: Kill process 12345 (node) score 987 or sacrifice child
Killed process 12345 (node)

✅ 恭喜你,问题已经 100% 坐实:就是 OOM/Killed。


6. 解决方案(推荐顺序):按这套做基本必好

方案 1(最推荐、立竿见影):给 Node 扩大内存

在 Jenkins 构建脚本里,在 npm run build 之前加:

bash 复制代码
export NODE_OPTIONS=--max_old_space_size=4096
npm run build

解释:

  • 4096 表示给 Node 堆内存上限 4GB
  • 16GB 机器完全够用
  • 如果机器只有 4GB,可用 2048

方案 2(必须做):让 Jenkins "失败就立刻停止",防止假成功

在脚本开头加:

bash 复制代码
set -e

或关键命令后面加:

bash 复制代码
npm run build || exit 1

效果:

  • 构建被 kill → 立刻 FAIL
  • 不会继续 zip/scp
  • 不会把半成品上传到生产

方案 3(Docker Jenkins 必看):检查容器内存限制

如果 Jenkins 在 Docker 里:

bash 复制代码
docker ps | grep jenkins

查看是否限内存:

bash 复制代码
docker inspect <容器名或ID> | grep -i memory

如果容器内存限制只有 2G/4G:

✅ 请把 Jenkins 容器内存调到 ≥ 6G(更稳 8G),否则你调 Node 参数也可能不生效。


方案 4(强烈建议):加 Swap 兜底

即使你有 16G 内存,建议也配一个 swap 防止尖峰:

bash 复制代码
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

验证:

bash 复制代码
free -h

看到 swap 非 0 即成功。


方案 5(优化项):降低构建内存峰值

可选但有效:

  • 关闭 sourcemap
  • 减少构建分析插件
  • 减少并行构建数(同一台机器同时跑多个 job 会爆)

7. 给你一份"可直接复制"的 Jenkins 构建脚本(前端)

适用于大多数 Vue/Vite/Webpack 项目:

bash 复制代码
#!/usr/bin/env bash
set -e

node -v
npm -v

# 关键:给 Node 足够的堆内存,防止 OOM/Killed
export NODE_OPTIONS="--max_old_space_size=4096"

npm ci
npm run build

# 可选:确保产物存在且完整(简单校验)
test -d dist || (echo "dist not found!" && exit 1)

8. 如果你还有 Java 后端(Maven)构建,也可以顺手稳一下

Maven 构建偶尔也会遇到内存不足或频繁 GC 导致慢:

bash 复制代码
export MAVEN_OPTS="-Xms1024m -Xmx4096m"
mvn -T 1C clean package -DskipTests

说明:

  • -T 1C:按 CPU 核心数并行(8 核会更快)
  • -DskipTests:不跑测试(看你需求)

9. 最佳实践:如何避免"产物不全还上线"的事故?

强烈建议你做两件事:

9.1 构建失败就不要上传

set -e 保证失败即中断。

9.2 上传前做产物校验

例如判断关键文件是否存在:

bash 复制代码
test -f dist/index.html || exit 1
ls dist/assets/*.js >/dev/null 2>&1 || exit 1

10. 常见 Q&A

Q1:我机器 16G,为什么 Node 默认还会 OOM?

A:Node 有自己的默认堆上限,并不会自动用满系统内存。需要 NODE_OPTIONS 手动放大。

Q2:为什么 Jenkins 显示 SUCCESS?

A:因为脚本没"失败即退出",后续步骤成功就可能导致 Jenkins 最终成功。

Q3:Sass 的 deprecated warning 是原因吗?

A:不是直接原因,但它提示你 SCSS 编译较多,可能提高内存峰值,从而更容易触发 OOM。


11. 总结(记住这句话就够)

Jenkins 构建日志出现 Killed,产物不完整但显示 SUCCESS
99% 是 Node 构建被 OOM Killer 干掉了

✅ 解决方案:
放大 Node 内存(NODE_OPTIONS) + 失败即中断(set -e) + 检查 Docker 限制/加 swap


相关推荐
tyatyatya17 小时前
Ansible自动化配置,从入门到实战
运维·自动化·ansible
Anakki17 小时前
企业级 Elastic Stack 集成架构:Spring Boot 3.x 与 Elasticsearch 8.x 深度实践指南
运维·jenkins·springboot·elastic search
DevOps-IT17 小时前
HTTP状态码(常见 HTTP Status Code 查询)
运维·服务器·网络·网络协议·http
释怀不想释怀17 小时前
Docker(安装软件)
运维·docker·容器
网硕互联的小客服17 小时前
服务器 CPU 温度过高需要进行的物理处理和软件处理有哪些?
运维·服务器
济61717 小时前
linux(第十三期)--filezilla使用方法(实现ubuntu和windows11文件互传)-- Ubuntu20.04
linux·运维·ubuntu
HIT_Weston17 小时前
91、【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(五)
linux·运维·ubuntu
阿巴~阿巴~17 小时前
从不可靠到100%可靠:TCP与网络设计的工程智慧全景解析
运维·服务器·网络·网络协议·tcp/ip·智能路由器
一殊酒18 小时前
【Figma】Figma自动化
运维·自动化·figma