尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Jenkins + GitHub 持续集成实战:从零搭建自动化构建流水线
1. 为什么我最终选择了 Jenkins GitHub 这套组合做开发这些年代码从本地到上线这条路我走过很多遍。早期靠手动打包、手动传服务器、手动重启服务一套流程下来少说十几分钟赶上改个小 bug 要反复来好几轮人很容易烦躁。后来团队人多了谁合并了代码、谁该负责构建、线上跑的是哪个版本全靠群里喊出问题就互相甩锅。这种状态持续了大概半年我下定决心要把持续集成这套东西搭起来。选型的时候其实纠结过一阵。市面上的持续集成工具不少有托管型的也有自建的。托管型的好处是开箱即用但代码要放到别人的平台上有些项目对代码存放位置有硬性要求走不通。自建的话Jenkins 是绕不开的选项——它开源、插件生态庞大、社区资料多最关键的是它能装在自己的机器上代码不出内网。配合 GitHub 做代码托管和 Webhook 触发整套链路就闭环了开发者往 GitHub 推代码GitHub 通过 Webhook 通知 JenkinsJenkins 拉代码、跑构建、执行测试、产出制品全程自动。这套组合解决的核心问题就三个第一把重复的构建动作自动化人不用再盯着第二让每次提交都有据可查构建记录、日志、产物都留痕第三把质量关卡前移测试不通过就别想合并。适合谁来参考我觉得只要你的项目需要频繁构建、需要多人协作、需要保证每次提交的质量这套东西就有价值。哪怕你是一个人开发的小项目搭起来之后也能省下大量重复劳动。下面我把自己踩过的坑、调过的参数、绕过的弯路完整地梳理一遍。2. 整体架构设计与核心思路拆解2.1 这套链路到底由哪几块拼起来先把整体图景说清楚不然后面配参数容易晕。整套环境由四个角色组成代码仓库GitHub、持续集成服务器Jenkins、构建执行节点可以是 Jenkins 本机也可以是独立机器、制品存放位置本地目录或对象存储。它们之间的数据流是这样的开发者在本地写完代码push 到 GitHub 的某个分支GitHub 检测到 push 事件根据配置好的 Webhook 地址向 Jenkins 发送一个 HTTP 请求请求体里带着这次提交的分支、commit id、提交人等信息Jenkins 收到请求后匹配对应的 Job触发一次构建构建过程中 Jenkins 会去 GitHub 拉取指定分支的代码然后按 Job 里定义的步骤依次执行——装依赖、编译、跑测试、打包最后把产物归档并把构建结果通过邮件或即时通讯工具通知出去。这个链路里Webhook 是自动化的触发点没有它就得靠定时轮询实时性差还浪费资源。Jenkins Job 是自动化的执行体所有构建逻辑都写在里面。构建节点是干活的机器如果构建任务多可以挂多个节点分担。制品归档是留痕的关键出了问题能回溯到具体是哪次构建产出的包。2.2 为什么不用定时轮询而用 WebhookJenkins 本身支持定时轮询 GitHub就是配一个 cron 表达式每隔几分钟去问一次“有没有新提交”。这种方式能用但有两个明显缺点。一是延迟你设 5 分钟轮询一次那最坏情况下提交后要等 5 分钟才触发构建反馈太慢。二是浪费大部分轮询都是空跑GitHub 的 API 调用次数也白白消耗。Webhook 是反过来由 GitHub 主动推事件给 Jenkins提交后几乎立刻触发而且只在有事件时才发请求效率高得多。不过 Webhook 有个前提Jenkins 必须能被 GitHub 访问到。如果你的 Jenkins 装在内网机器上GitHub 的公网请求进不来那就只能用轮询或者在内网出口做一层转发。这一点在动手之前一定要先确认否则配了半天 Webhook 发现根本收不到请求白忙活。2.3 构建节点的选择本机还是独立机器刚开始搭的时候我图省事直接把构建任务跑在 Jenkins 本机上。小项目没问题但任务一多就出状况构建过程吃内存、吃 CPUJenkins 主进程跟着卡Web 界面响应变慢严重的时候连 Webhook 都处理不过来。后来我把构建任务拆到独立的节点上Jenkins 主服务器只负责调度和展示构建节点专门干活两边互不影响。判断标准很简单如果构建任务超过 5 个或者单个构建耗时超过 3 分钟就建议拆节点。拆节点的方式是在 Jenkins 里添加节点通过 SSH 或者 JNLP 方式连接。SSH 方式更稳定配置也简单只要目标机器开了 SSH 服务、配好密钥就行。JNLP 方式适合目标机器在内网、Jenkins 在外网的情况但配置起来麻烦一些。3. 环境准备与核心组件安装实操3.1 基础环境要求与依赖清单动手之前先把基础环境理清楚。Jenkins 是 Java 写的所以JDK 是必须的。我实测下来JDK 11 和 JDK 17 都能跑但有些老插件对 JDK 17 支持不好如果追求稳定JDK 11 是更稳妥的选择。内存方面Jenkins 本体加上构建任务至少给 4GB如果构建任务重8GB 起步。磁盘要留足构建产物、日志、工作空间都会占空间建议单独挂一块数据盘别跟系统盘混在一起不然日志写满系统盘会直接导致服务挂掉。除了 JDK还需要Git 客户端Jenkins 拉代码靠它。如果构建的是前端项目还得装Node.js如果是 Java 项目得装Maven 或 Gradle。这些工具不用提前全装等配具体 Job 的时候按需装就行但心里要有数。组件版本建议作用是否必须JDK11 或 17运行 Jenkins 本体必须Git2.30 以上拉取代码必须Maven3.6 以上Java 项目构建按需Node.js16 或 18前端项目构建按需Docker20 以上容器化构建按需3.2 Jenkins 安装的两种方式与取舍安装 Jenkins 有两条路包管理器安装和容器化安装。包管理器安装就是通过系统的 apt 或 yum 直接装好处是跟系统集成好开机自启、日志管理都现成坏处是升级麻烦插件依赖冲突的时候不好回滚。容器化安装是把 Jenkins 跑在容器里好处是环境隔离干净、升级就是换个镜像、迁移方便坏处是容器里的 Jenkins 要访问宿主机的 Docker 或者构建工具得额外挂载配置稍复杂。我个人的选择是容器化安装因为构建环境经常要变容器化之后每个 Job 可以用不同的镜像互不干扰。具体做法是拉一个官方镜像把 Jenkins 的工作目录挂载到宿主机上这样容器删了数据还在。启动命令大概是这样docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v /data/jenkins:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ jenkins/jenkins:lts这里有几个点要说明。8080 是 Web 界面端口50000 是节点通信端口如果不用独立节点50000 可以不映射。挂载 docker.sock 是为了让容器里的 Jenkins 能调用宿主机的 Docker这样构建镜像、起容器都方便。挂载 /usr/bin/docker 是因为容器里没装 docker 客户端直接借用宿主机的。启动之后访问 8080 端口会要求输入初始密码密码在容器的日志里用docker logs jenkins能看到。3.3 初始配置与插件安装策略第一次进 Jenkins 界面它会让你选装插件。这里有个坑默认的“安装推荐插件”会装一大堆你可能用不上的东西装多了拖慢启动速度还容易出插件冲突。我的做法是选“不安装”进去之后按需装。必须装的插件有这么几个Git plugin拉代码、GitHub plugin跟 GitHub 集成、Pipeline写流水线、Credentials Binding管理凭据、Email Extension发邮件通知。如果要用 Docker 构建再加Docker Pipeline。装插件的时候注意有些插件之间有依赖关系装一个会自动带上依赖的这是正常的。但如果装完提示有插件版本冲突别硬装先把冲突的插件降级或者升级到兼容版本。我遇到过一次 Git 插件和 GitHub 插件版本不匹配导致 Webhook 触发不了排查了半天才发现是版本问题。提示插件装完之后建议重启一次 Jenkins让所有插件完全加载。重启命令在“系统管理”里能找到或者直接重启容器。4. 打通 GitHub 与 Jenkins 的关键配置4.1 凭据管理让 Jenkins 有权限访问 GitHubJenkins 要拉 GitHub 的代码得有权限。权限的载体就是凭据。GitHub 这边有两种方式用户名密码和个人访问令牌。用户名密码方式简单但安全性差而且 GitHub 已经不支持用密码做 Git 操作了所以实际只能用令牌。令牌的生成在 GitHub 的开发者设置里勾选repo和admin:repo_hook权限就够了前者是读写代码后者是管理 Webhook。生成令牌之后到 Jenkins 的“凭据”页面添加类型选“Secret text”把令牌粘进去起个能认出来的 ID比如github-token。这个 ID 后面配 Job 的时候要用到。令牌要妥善保管一旦泄露等于代码仓库的钥匙给了别人。如果怀疑泄露了第一时间去 GitHub 撤销重新生成。4.2 Webhook 配置与网络连通性验证Webhook 的配置在 GitHub 仓库的“Settings - Webhooks”里。点“Add webhook”Payload URL 填 Jenkins 的地址加上/github-webhook/注意结尾的斜杠不能少少了会 404。Content type 选application/json。触发事件选“Just the push event”这样只有 push 的时候才通知减少无效请求。配完之后 GitHub 会发一个测试请求如果 Jenkins 那边配置正确会显示一个绿色的勾。如果显示红色说明请求没送达或者被拒绝了。排查思路先看 Jenkins 的日志有没有收到请求没收到就是网络不通检查防火墙、端口映射收到了但报错就是 Jenkins 这边的 Job 没配好或者令牌权限不够。注意如果 Jenkins 用的是 HTTP 而不是 HTTPSGitHub 可能会拒绝发送请求。生产环境建议上 HTTPS自签证书也行但要在 Jenkins 的启动参数里信任这个证书。4.3 Job 类型选择自由风格还是流水线Jenkins 的 Job 有两种主要类型自由风格和流水线。自由风格是图形界面点点点适合简单任务上手快流水线是写代码Jenkinsfile适合复杂流程可版本化、可复用。我强烈建议用流水线理由有三个一是流水线配置能跟代码一起存在仓库里改配置走代码评审有记录二是流水线支持更复杂的逻辑比如并行执行、条件判断、循环三是流水线容易复用多个项目可以共用一套模板。流水线又分两种写法脚本式和声明式。脚本式灵活但语法松散声明式结构清晰、约束强新手更容易上手。我推荐用声明式它的结构是固定的pipeline { agent ... stages { stage ... } }照着填就行。5. 流水线脚本编写与构建流程实现5.1 一个完整的声明式流水线骨架先看一个能跑起来的最小骨架理解了结构再往里填内容pipeline { agent any stages { stage(拉取代码) { steps { checkout scm } } stage(编译构建) { steps { sh mvn clean package -DskipTests } } stage(运行测试) { steps { sh mvn test } } stage(归档产物) { steps { archiveArtifacts artifacts: target/*.jar, fingerprint: true } } } post { success { echo 构建成功 } failure { echo 构建失败 } } }这个骨架里agent any表示用任意可用节点。stages里每个stage是一个阶段按顺序执行。steps里是具体命令。post是构建后的动作成功失败分别处理。这个结构是声明式的标准写法所有流水线都长这样区别只是 stage 的数量和内容。5.2 拉取代码阶段的参数细节checkout scm是个简写它会根据 Job 的源码管理配置自动拉代码。但如果你想在流水线里显式指定仓库地址和分支可以写全stage(拉取代码) { steps { git branch: main, credentialsId: github-token, url: https://github.com/your-org/your-repo.git } }这里credentialsId就是前面配的凭据 ID。分支名要写对写错了会拉不到代码报错信息一般是“Couldnt find any revision to build”。如果仓库是私有的credentialsId必须配否则会提示认证失败。拉代码的时候建议只拉最近一次提交用shallowClone: true参数能加快速度尤其是仓库历史很长的时候。5.3 构建与测试阶段的实操要点构建阶段就是执行编译命令。Java 项目用 Maven 的话mvn clean package是标配。加-DskipTests是为了先跳过测试快速出包测试放到下一个阶段单独跑这样测试失败的时候能清楚知道是测试的问题还是编译的问题。前端项目用npm install npm run build注意npm install要加--registry指定镜像源不然拉包慢得让人抓狂。测试阶段跑mvn test或者npm test。测试结果要归档不然 Jenkins 界面上看不到测试报告。Maven 项目加junit target/surefire-reports/*.xml前端项目用对应的报告插件。测试失败的时候流水线会中断后面的阶段不执行这是符合预期的——测试不过就不该继续。实操心得构建和测试分开两个 stage不要合在一起。合在一起的话构建日志和测试日志混在一块排查问题很痛苦。分开之后哪个阶段挂了看哪个阶段的日志一目了然。5.4 制品归档与通知机制制品归档用archiveArtifacts把构建产出的包存到 Jenkins 的归档目录里。fingerprint: true会记录制品的指纹方便追踪哪个构建产出了哪个包。归档的制品可以在 Jenkins 界面上直接下载也能通过 API 获取。通知机制我配了两种邮件和即时通讯。邮件用 Email Extension 插件配好 SMTP 服务器在post里根据构建结果发不同内容的邮件。即时通讯用 Webhook 方式构建结束后调一个接口把结果推过去。通知内容要包含关键信息项目名、构建号、分支、提交人、构建结果、耗时、日志链接。信息不全的通知等于没通知还得点进去看。6. 常见问题排查与避坑经验实录6.1 Webhook 触发不了怎么排查这是最高频的问题。排查顺序是这样的第一步确认 Jenkins 的 Webhook 地址能公网访问用手机浏览器或者在线工具访问一下看能不能通。第二步看 GitHub 的 Webhook 记录在仓库的 Webhook 设置里点进去能看到每次请求的详情包括响应码和响应体。第三步看 Jenkins 的日志如果 GitHub 发了请求但 Jenkins 没反应日志里会有记录。第四步检查 Job 的触发配置流水线 Job 要勾选“GitHub hook trigger for GITScm polling”不勾的话收到请求也不触发。我遇到过一次Webhook 显示 200 但 Job 不触发查了半天发现是 Job 里的分支过滤写错了只允许main分支触发但实际推的是master分支。分支名一定要跟实际一致GitHub 默认分支可能是main也可能是master看仓库创建的时间。6.2 构建环境不一致导致的诡异失败同一个 Job在 A 机器上成功在 B 机器上失败这种问题最让人头疼。根因通常是环境不一致JDK 版本不同、Maven 版本不同、环境变量不同。解决办法是用容器化构建把构建环境固化到镜像里每次构建都从同一个镜像起容器环境绝对一致。如果暂时上不了容器那就把环境信息打印出来。在流水线开头加一段sh java -version sh mvn -version sh echo $PATH这样构建日志里就有环境信息对比成功和失败的日志差异一目了然。6.3 构建速度慢的优化方向构建慢的原因通常有三个拉代码慢、装依赖慢、构建本身慢。拉代码慢用浅克隆解决前面提过。装依赖慢用缓存解决Maven 的.m2目录、npm 的node_modules目录都可以缓存Jenkins 的流水线支持cache指令或者手动挂载缓存目录。构建本身慢就得看具体项目了可能是编译参数没优化也可能是测试用例太多这个得具体分析。问题现象可能原因解决方向拉代码耗时超过 1 分钟仓库历史太长开启浅克隆装依赖耗时超过 3 分钟没有缓存挂载缓存目录构建耗时波动大节点资源竞争拆分节点或限制并发测试阶段特别慢测试用例过多拆分测试或并行执行6.4 凭据失效与权限问题凭据失效的典型表现是拉代码时报 401 或 403。原因通常是令牌过期或被撤销。GitHub 的令牌可以设置有效期到期自动失效。解决办法是重新生成令牌更新 Jenkins 里的凭据。建议令牌设置较长的有效期或者用不过期的令牌但要注意安全。权限问题的另一种表现是 Webhook 配置不了提示没有权限。这是因为生成令牌的时候没勾admin:repo_hook权限。重新生成令牌把权限勾全。7. 我踩过的几个印象深刻的坑第一个坑是磁盘写满导致 Jenkins 挂掉。构建日志和制品越积越多把数据盘写满了Jenkins 直接起不来。后来我加了一个清理策略在 Job 里配置“保留最近 10 次构建”旧的自动删。同时监控磁盘使用率超过 80% 就告警。第二个坑是并发构建冲突。同一个 Job 同时触发两次两次构建往同一个工作空间写文件互相覆盖结果两边都失败。解决办法是在 Job 里勾选“不允许并发构建”或者用disableConcurrentBuilds()指令。如果确实需要并发那就给每次构建分配独立的工作空间。第三个坑是插件升级导致流水线语法不兼容。有一次升级了 Pipeline 插件新版本对某些语法做了调整老的 Jenkinsfile 跑不了了。教训是升级插件前先在测试环境验证别直接在生产上升。如果非升不可先把 Jenkins 的配置备份一份出问题能回滚。第四个坑是通知发不出去。邮件通知配好了但收不到查了半天发现是 SMTP 服务器的端口被防火墙拦了。换成 465 端口SSL就通了。通知这种辅助功能出问题不影响构建但影响体验配的时候顺手测一下别等构建失败了才发现通知没发出去。8. 后续可以继续扩展的方向这套环境跑稳之后可以往上加的东西还不少。代码质量扫描可以集成静态分析工具每次构建自动扫一遍把问题扼杀在合并之前。自动化部署可以在构建成功后自动把包推到测试环境省去手动部署的步骤。多分支流水线可以给每个分支自动创建 Job适合分支多的项目。构建矩阵可以同时跑多个 JDK 版本、多个操作系统的组合适合需要跨平台验证的项目。我个人在实际操作中的体会是持续集成这套东西搭起来只是第一步用起来、用顺才是关键。一开始别追求大而全先把最核心的“提交即构建”跑通让团队养成看构建结果的习惯再逐步往上加东西。加得太快太猛团队跟不上反而容易抵触。另外构建失败的通知一定要及时且明确谁提交的代码导致失败第一时间让谁知道这样修复才快。构建红了没人管这套东西就形同虚设了。
RELATED

相关推荐

BMS电池均衡设计实战:从电芯不一致到主动均衡选型与调试

BMS电池均衡设计实战:从电芯不一致到主动均衡选型与调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/16 1:01:27
应届生求职网职位信息函数化爬取:从请求封装到数据清洗的完整教程

应届生求职网职位信息函数化爬取:从请求封装到数据清洗的完整教程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/16 1:01:27
C语言期末305道题高效刷题指南:从分诊到考场

C语言期末305道题高效刷题指南:从分诊到考场

简介:这份资源是面向高校学生的C语言期末备考题库,以PDF形式提供305道题目及详细解析,适合正在准备C语言期末考试、需要系统刷题与查漏补缺的学习者。题库覆盖选择题、填空题、判断题、读程序写结果以及压轴编码大题等经典题型,内…

📅 2026/10/16 0:56:27
MORE NEWS

更多资讯

📰

Spring Boot三层架构核心解析:职责边界、事务控制与常见坑

1. 三层架构的真面目:不只是分包那么简单我刚带项目组那会儿,最常被新人问的一个问题就是:“这代码到底该往哪一层写?”很多同学能背出“Controller是控制层、Service是业务层、Mapper是数据层”,可真到写代码的时候&a…

📰

Anaconda安装PyTorch GPU版:十分钟搞定CUDA环境配置

很多第一次碰深度学习的人,卡住的往往不是模型怎么写,而是环境装不对。明明照着教程敲了三行命令,torch.cuda.is_available()还是返回False,然后开始怀疑显卡、怀疑驱动、怀疑人生。其实在 Anaconda 里装 PyTorch GPU 版这件事&am…

📰

LangChain与LangGraph怎么选?从本质差异到学习路线全解析

这段时间私信里问得最多的一个问题,已经从"怎么把对话记录传给模型"变成了"LangChain和LangGraph到底该学哪个、项目里到底用哪个"。我能理解这种纠结,因为LangChain官方文档一边把重心往LangGraph上偏,一边又在自己博客…

📰

JDK8 HashMap源码拆解:散列、红黑树与扩容机制一次讲透

1. 先看清HashMap的底层结构:数组、链表、红黑树是怎么拼在一起的HashMap大概是Java容器里被面试官问得最多、被线上故障坑得最惨的一个类。我最早认真读它的源码,正因为某个跨平台系统的压测频繁出现CPU100%,抓完线程栈发现所有线程都卡在Ha…

📰

ARM64中断处理全链路解析:从GIC硬件触发到Linux驱动回调

这段时间一直在调一块 ARM64 板卡上的外设中断丢事件问题,被迫把 ARM64 中断处理这条路从头到尾捋了一遍。说实话,网上讲 ARM64 中断的文章不少,但大多停留在"GIC 是中断控制器、内核里有中断子系统"这种概念层面,真正从…

📰

AI日报系统设计:分层流水线架构与本地化实践

1. 项目概述:这不是一份新闻简报,而是一套可复用的AI信息流处理系统“AI 日报(2026年10月8日)”这个标题乍看像一份时效性极强的媒体简报,但作为从业十多年、亲手搭建过二十多个垂直领域信息聚合系统的博主&#xff0c…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬