ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Jenkins重启实操指南:三种方式与常见坑位

Jenkins重启实操指南:三种方式与常见坑位 上周五下午我正打算给 Jenkins 装一个新插件结果刚点完安装页面就卡死在转圈状态。任务队列里还挂着二十几个构建群里同事已经开始刷屏问“构建怎么都不动了”。我当时脑子里闪过的第一个念头就是赶紧重启一下。但第二个念头马上追上来了——万一这一下把所有运行中的任务全掐了插件又没装好起来之后连 Job 配置都读不出来那才叫真翻车。后来控制住冲动先看了一眼节点状态再决定用哪种方式重启。这次经历让我把“重启 Jenkins”这件事彻底想明白了它远不是点个按钮那么简单跟部署方式、当前任务状态、配置存储位置都强相关。这篇笔记就结合我自己的实操踩坑把重启 Jenkins 的三种主要方式、各自的适用场景以及重启之后容易翻车的点一次性讲清楚。不管是刚接触 Jenkins 的菜鸟还是已经跑了好几年流水线的老手应该都能从中找到点参考。1. 重启之前先想清楚直接重启还是安全重启1.1 restart 和 safeRestart 到底差在哪先说结论Jenkins 提供的重启入口从语义上可以分成两类直接重启和“安全重启”。直接重启对应 URL 是/restart。当你在浏览器里访问这个地址的时候Jenkins 会立刻让当前进程退出再重新拉起来一个新的进程。运行中的构建任务会被打断执行中的耗时操作比如正在拉代码、正在执行 shell也会一并中断。这个方式的价值体现在“快”上适合 Jenkins 已经明显假死、页面半天没响应、日志也不怎么滚动的情况这时候再等下去没有意义。安全重启对应 URL 是/safeRestart。它的行为是Jenkins 先进入“不再接受新任务”的状态当前正在运行的构建任务会继续执行等这些任务全部结束之后再执行重启。队列里等待的任务不会丢重启后继续排队。这个方式的价值在于“稳”。需要强调一下如果有一个任务因为外部原因挂死比如远程节点掉线、脚本死循环safeRestart 会一直卡在等待状态等一小时也等不出结果。遇到这种情况先确认没有异常任务或者手动把死任务终止掉再执行安全重启。补充一个和这两个 URL 容易混淆的入口/prepareShutdown。它只触发安全关闭模式Jenkins 会停止接收新任务等现有任务跑完最后停下并不自动重启。有些运维同事会把它和 safeRestart 混为一谈其实一个是“关了就停”一个是“停完再开”。1.2 判断依据这些情况才真的需要重启很多刚接触 Jenkins 的人遇到问题第一个反应就是重启。我不否认重启确实能解决不少莫名奇妙的问题它甚至一度被戏称为“运维三大法宝”之一。但频繁重启会带来两个很现实的副作用一是打断团队正在跑的流水线二是如果数据写入刚好发生在进程被杀的一瞬间可能导致配置损坏。所以动手之前先问自己一句这个问题是重启能解决的吗一般来说下面这些场景才属于“必须重启”Jenkins 主版本升级或安装/卸载插件后系统明确提示需要重启修改了 JVM 参数、HTTP/HTTPS 端口、--prefix访问前缀等启动级参数调整了执行者数量、Jenkins URL 这类需要重新加载才能生效的全局配置进程明显异常比如内存飙高、Full GC 打满、页面无法访问、日志不再输出。而下面这些操作通常不需要重启修改某个 Job 的构建步骤、调整定时触发规则、新增凭据、配置系统邮件通知、调整全局工具路径、修改权限矩阵。这些内容大部分在点击“保存”的瞬间就已经生效了。如果你不确定某个配置到底要不要重启可以在配置页保存之后观察一下再找个低峰期测试而不是立刻点重启。这也是为什么网上经常有人搜“jenkins 不重启能不能生效”这类问题——答案多数时候是能不能生效看的是配置类型不是玄学。1.3 重启之前的三分钟准备无论你最后选择哪种方式动手前一定花几分钟做三件事这几分钟能帮你避免 90% 的返工。第一备份 JENKINS_HOME 的关键内容。不用每次做全量快照那么夸张但至少把config.xml、jobs/、users/、plugins/这几个目录打包带走。我一般用tar czf jenkins_backup_$(date %Y%m%d).tgz $JENKINS_HOME --excludelogs一两分钟搞定放在其他磁盘。如果 Jenkins 跑在虚拟机上更省事的办法是直接做一次虚拟机快照。第二记录当前运行状态。正在跑的构建有几个、队列里等待的任务有多少、分布式节点是不是全部在线。这些信息不只是为了心里有数重启之后可以用来核对结果。用命令查也很方便curl -s -u admin:你的token http://localhost:8080/computer/api/json?prettytrue可以看节点状态curl -s -u admin:你的token http://localhost:8080/queue/api/json能看队列。第三看一眼磁盘空间和日志尾巴。磁盘满了是导致重启失败的大户df -h确认一下/和 JENKINS_HOME 所在分区的剩余容量。日志建议直接看启动时的 console 日志或者/var/log/jenkins/jenkins.log如果最后几行已经出现java.lang.OutOfMemoryError等字样那重启之前最好先把内存参数调一下否则重启完还是同样的问题。2. 方式一Web 界面触发重启方便但别忽略权限和超时2.1 三种 URL 触达姿势Web 界面触发重启是最直观的方式适合 Jenkins 网页还能访问的情况。具体做法分几种直接浏览器访问/restart确认后立即重启访问/safeRestart按前面说的安全重启逻辑执行如果插件装到一半挂在那里也可以访问/pluginManager/左侧有时会显示“在重启后安装完成”的提示操作后一般会引导你触发重启。另外系统管理左侧菜单中有一个“准备关机Prepare for Shutdown”入口点击后进入安全关闭状态。它的作用和/prepareShutdown一样不会自动拉起进程。如果系统已经关闭了需要到服务器上用服务命令把 Jenkins 启动起来也可以把这个入口理解为“给手动重启铺路”。2.2 点击重启之后页面卡住别乱刷用 Web 方式重启时有个很常见的现象页面停在“正在关闭”或“Please wait”状态愣是几分钟没反应。这时候很多人会忍不住反复刷新。我的建议是刷新可以但别太频繁至少间隔半分钟以上否则在浏览器端容易重复提交请求虽然实际触发会有判断但没必要给系统增加额外压力。判断重启是否正常完成最靠谱的动作是看服务端日志。如果你用 systemd 管理执行journalctl -u jenkins -f看到类似Jenkins is fully up and running或者平时启动完成的那行日志再刷新页面也不迟。如果你用的是手动启动方式日志会输出在你重定向的 console 文件里同样可以先 tail 观察。如果页面一直显示“服务不可用”不要直接断定重启失败先确认端口是否在监听。比如ss -lntp | grep 8080端口有监听再等一下端口没监听但进程还在说明可能是防火墙或代理挡住。2.3 权限、反向代理与超时问题Web 方式有一个容易忽略的点权限。能触发/restart或/safeRestart的前提是当前登录用户拥有管理权限一般就是Overall/Administer。如果没有权限访问/restart会得到一个 403 或者被重定向到登录页。有些团队为了省事给很多成员都配了管理权限这相当于把重启能力散了一地一个手误就可能打断整个生产流水线。建议把权限收敛让少数人来管“重启”这种敏感操作。另一个坑和反向代理有关。如果 Jenkins 放在 Nginx 或负载均衡后面并且代理层设置了较短的proxy_read_timeout你点击重启后前端可能先收到一个 502/504让人觉得失败了。但实际上后端的 Jenkins 进程很可能已经开始正常重启。所以遇到网关报错先看后端日志和进程状态别急着在服务器上再杀一遍进程。Web 方式说白了适合单机、非核心时段、或者页面还能正常打开的时候。一旦服务彻底访问不了这个入口就用不上了往下看服务命令和进程的方式。3. 方式二系统服务命令管理最贴近运维日常3.1 Linux 下 systemd 和 init.d 的重启命令如果你的 Jenkins 是用系统自带方式安装的比如通过 apt 或 yum 装了 Jenkins 包那么最规范的重启方式就是服务管理命令。在新发行版上基本都用 systemdsystemctl restart jenkins需要看重启过程中的日志用journalctl -u jenkins -f想知道当前是不是正在运行systemctl status jenkins如果是比较老的系统还在用 SysV init那就用service jenkins restart本质上等价于/etc/init.d/jenkins restart。这两种方式的共同好处是服务管理器会以正确的用户身份启动 Java 进程读取/etc/default/jenkinsDebian/Ubuntu或/etc/sysconfig/jenkinsRHEL/CentOS里面的环境变量和 JVM 参数并且能提供开机自启、异常重启等能力。3.2 环境变量配置文件的正确维护方式这里要延展一句好多“重启后环境变量丢失”的问题根子不在重启本身而在环境变量写错了地方。比如有人喜欢在命令行里临时export JENKINS_HOME...然后直接java -jar启动。这种方式在重启前确实能用但只要系统或进程一重启就全没了。正确的做法是把变量固化到服务配置里。Debian/Ubuntu 下打开/etc/default/jenkins常见的有JAVA_HOME/usr/lib/jvm/java-17-openjdk-amd64 JENKINS_HOME/var/lib/jenkins JAVA_ARGS-Xms2g -Xmx4g -Djava.awt.headlesstrueRHEL/CentOS 对应/etc/sysconfig/jenkins。改完之后直接systemctl restart jenkins就会生效。注意如果你改的是 systemd 的 unit 文件本身需要先跑一下systemctl daemon-reload再 restart只改上面的环境变量文件则不需要。还有一个容易踩的配置文件里的变量值如果包含特殊字符记得用双引号包起来比如路径里带空格或者-D参数多的时候。写错了 Jenkins 启动时可能直接报错但报错信息不一定明显有时候只是日志在启动几秒后就停止所以改完配置第一时间看日志别等着页面起来。3.3 Windows 服务与 Tomcat 容器里的处理Windows 上如果用安装包安装Jenkins 会注册为一个 Windows 服务服务名一般就叫 Jenkins。在管理员权限的 cmd 或者 PowerShell 里可以执行net stop Jenkins net start Jenkins或者直接用 PowerShellRestart-Service Jenkins注意一点Windows 服务方式下服务停止命令执行完Java 进程不一定立刻退出尤其是某些版本 Jenkins 在处理关闭钩子时比较慢。如果紧接着执行启动命令可能会报端口占用。稳妥的办法是在 stop 和 start 之间加个几秒等待或者先确认 8080 端口已经释放再启动。如果 Jenkins 是部署在 Tomcat 里的 war 包应用那重启的其实是 Tomcat 服务。这时候你同样用systemctl restart tomcat或 Windows 服务来重启但要额外区分JENKINS_HOME和 Tomcat 的CATALINA_HOME别把两份目录搞混。很多 Tomcat 部署方式下JENKINS_HOME 默认在~/.jenkins除非你在启动脚本里显式指定否则数据位置和原来不一定一致这是极其常见的“重启后变成新实例”事故源头。3.4 Docker 容器里的重启差异容器化部署现在是主流很多团队的 Jenkins 就跑在 Docker 里。最简单的重启是docker restart jenkins或者用 compose 的话docker compose restart jenkins这里有个特别容易忽略的要点docker restart只是重启容器它不会重新创建容器所以不会应用你新修改的端口映射、环境变量或挂载配置。如果你改了docker-compose.yml或者docker run参数仅仅 restart 是不生效的必须用docker compose up -d来重新创建容器。同时容器能不能安全重启取决于数据有没有挂载出来。如果JENKINS_HOME没有挂到宿主机或 Volume 里docker restart虽然保留容器内的数据但一旦你执行docker rm或者容器被清理数据就彻底没了。正确做法是把JENKINS_HOME挂载到宿主机目录比如-v /var/jenkins_home:/var/jenkins_home。另外新版官方镜像默认用jenkins用户运行挂载目录如果权限不对启动时会因为无法写文件而失败排错时先看挂载目录的所有者。3.5 为什么我建议把服务方式当成默认动作讲了三种系统环境下的服务管理命令并不是说要你每次都跑到服务器上去敲。但相比 Web 方式和直接杀进程服务方式有一个核心优势它使用的是“正规启动链路”启动用户、环境变量、JVM 参数、守护和管理逻辑都齐了。你不用担心因为当前 shell 环境不对导致启动出来的 Jenkins 行为和原来不一样。我之前遇到过一位同事为了图快直接杀掉 java 进程后用 root 用户手动nohup java -jar把 Jenkins 拉起来结果插件目录的属主变成了 root后续 Jenkins 更新插件时因为权限问题一直失败。这种问题排查起来非常绕。所以只要这台机器上有可用的服务管理方式优先用它手动进程方式只作为应急兜底。4. 方式三找到 PID 直接杀进程再手动拉起——应急手段也要讲章法4.1 找 PID别把多个实例混为一谈如果 Web 页面打不开、服务管理命令又找不到这个服务比如你是下载 war 包手动部署的那就只能回到“进程管理”这个层面。Linux 下找 Jenkins 进程很简单ps -ef | grep jenkins pgrep -f jenkins.war你会发现输出里有个java -jar /usr/lib/jenkins/jenkins.war或类似路径这就是主进程。pgrep -f比grep更精准直接返回 PID。如果机器上跑了很多 Java 应用还可以用jps -l它只列出 Java 进程能清楚看到 jar 或主类路径。Windows 下稍微麻烦一点可以先试Get-CimInstance Win32_Process -Filter namejava.exe | Where-Object { $_.CommandLine -like *jenkins.war* } | Select ProcessId,CommandLine这里我强调“先确认再动手”如果机器上有两个 Java 进程都包含 jenkins 字样比如一个是 Master 一个是 Agent杀之前要看命令行参数里-jar路径、端口、-master地址等字段。更稳妥的方法是先看端口归属Linux 用ss -lntp | grep 8080Windows 用netstat -ano | findstr :8080通过 PID 反查哪个进程占用了 Jenkins 的监听端口。4.2 杀进程用 TERM能不用 KILL 就别用确定 PID 之后先发温和的信号kill -TERM 1234512345替换成 PID。Jenkins 的 Java 进程收到 TERM 信号后会走 JVM 关闭钩子尽量保存状态、释放资源等它正常退出。如果过了十秒二十秒进程还在再考虑kill -KILL 12345强制结束。我见过不少人对 Java 进程用kill -9用得特别顺手好像多等一秒就是浪费。但 Jenkins 这种带大量状态的应用强制杀进程除了可能留下*.lock文件锁严重时还会导致 XML 配置写入一半损坏重启后整个 Job 都读不出来。所以能温和就温和。另外千万不要对 Java 进程使用kill -HUP。Nginx 里 HUP 信号可以重载配置但 Jenkins以及绝大多数 Java 应用并没有实现这个处理逻辑发 HUP 信号的结果经常是进程直接退出。4.3 手动拉起的完整命令和隐藏的坑进程杀掉之后需要手动把 Jenkins 拉起来。基础命令大概长这样export JENKINS_HOME/var/lib/jenkins nohup java -jar /usr/lib/jenkins/jenkins.war \ --httpPort8080 \ --prefix/jenkins \ /var/log/jenkins/jenkins-console.log 21 参数根据自己的启动参数调整以前怎么起的现在就怎么起。这里有几个我踩过很多次的坑忘记设置JENKINS_HOME。如果没设置默认会落到当前用户的~/.jenkins页面起来后看着像是全新实例配置、Job、插件全都不见了。这个错最吓人但也好排查看到空页面第一反应就要检查环境变量。用错用户。前面说过手动用 root 启动会导致插件目录属主变更后续用原服务用户更新插件时权限出问题。除非你确认原来就是 root 启动否则尽量切到jenkins用户再起。日志父目录不存在。 /var/log/jenkins/jenkins-console.log会创建文件但如果/var/log/jenkins目录不存在shell 会直接报错进程起不来。先mkdir -p。nohup和不能少。少了nohupSSH 断开时进程可能被 SIGHUP 干掉少了命令一直占住终端一旦终端关闭进程也会跟着没了。手动拉起这种方式适合应急恢复和临时调试但我不建议把它作为长期运行方案。原因很简单没有服务管理器盯着进程一旦挂了不会自动拉起开机也不会自启出了问题全靠人工发现。5. 重启之后最容易翻车的三个地方5.1 环境变量一夜回到解放前这是重启后最常见的故障而且往往不是立刻爆发。比如 Jenkins 之前能用mvn、docker、kubectl这些命令重启后 Pipeline 里执行到同一段 shell 却报了command not found。原因很简单这些命令的路径原本依赖某个用户在.bashrc里临时加的 PATH或者在当前 shell 会话里 export 过而 Jenkins 服务启动时并没有读到那些配置。排查思路先在服务配置里确认有没有设置PATH或额外工具路径。Jenkins 侧可以在“系统管理 → 系统设置 → 全局属性”里添加MAVEN_HOME、JAVA_HOME等环境变量并在 Pipeline 中通过这些变量去调用工具。另外如果原来是通过docker命令执行容器化构建还需确认 Docker 服务和当前用户是否有权限访问 Docker 的 socket重启后用户组权限会变这种问题更隐蔽。给一个快速对照表环境变量常见配置位置重启后影响JENKINS_HOME/etc/default/jenkins、/etc/sysconfig/jenkins、Docker env配置和数据加载位置JAVA_HOME服务配置文件、Jenkins 工具配置Java 工具链调用失败MAVEN_HOMEJenkins 全局工具配置Maven 构建找不到命令PATH服务配置 全局属性shell 步骤命令找不到DOCKER_HOST服务配置、Pipeline envdocker 命令连不上守护进程5.2 插件加载失败和静态资源错乱重启后如果发现某个插件功能不见了或者系统管理页面提示Failed to load plugin不要慌先看日志定位是哪个插件。常见原因是插件 jar 包损坏、插件之间版本不兼容、或者插件依赖的底层库被其他插件覆盖。处理思路是到插件管理页面搜索问题插件重新安装对应版本如果页面已经进不去就手动到$JENKINS_HOME/plugins目录把对应.jpi/.hpi文件移走再重启一般能恢复。还有一个表现很迷惑页面上图标全丢、样式错乱、按钮点了没反应。这大概率是浏览器缓存了旧版本的静态资源和新版 war 解压出来的前端资源对不上。处理时先让用户强制刷新或清理缓存不要在服务器上瞎删文件。如果你在服务器端想清一下 Jenkins 自己的 war 解压缓存通常$JENKINS_HOME/war目录会在启动时重新生成但生产环境我不建议随便删除非你非常确定。5.3 构建队列、自动部署和 GitLab 连接恢复安全重启之后队列里的构建任务会保留直接重启的话正在运行的任务会被打断队列中尚未开始的任务在界面上可能还显示着但实际已经不可执行需要在队列管理中手动取消再重新触发。这是我每次在团队里强调“能安全重启就安全重启”的另一个原因。自动部署方面Jenkins 本身没有错过即补跑的机制。定时任务是按 Cron 表达式在下次匹配时间再触发不会因为你中间关了一个小时就把这段时间内该跑的任务补上。Webhook 触发的任务则依赖于外部系统回调比如 GitLab 提交代码后发送 webhook。重启后如果 GitLab 的 webhook 连不上重点不是看 Jenkins而是看“系统设置 → Jenkins Location → Jenkins URL”填的是不是外部能访问的地址。经常有人重启前一切正常重启后 GitLab 开始报连接失败查到最后是 Jenkins URL 里写着 localhost或者证书过期和重启并没有直接关系。分布式节点也一样。如果你用的是 Jenkins Agent 的永久连接方式Master 重启后 Agent 一般会自动重连临时用命令行启动的 agent 进程则可能已经退出需要重新拉起。建议在 Agent 配置中开启“当 Master 离线时保持连接/自动重连”相关选项能少很多麻烦。6. 什么时候其实不用重启热加载、脚本控制台与 CLI 变通6.1 大多数配置保存即生效别把重启当成条件反射很多新人搜“jenkins 不重启”是想知道改完配置到底要不要重启。这个答案因配置而异但大方向是配置类改动基本保存即生效。比如修改 Job 的 Git 分支、调整构建参数、添加视图、配置凭据、修改权限矩阵点击保存后立即生效。全局工具配置里如果只是改了 JDK 或 Maven 的路径也无需重启下次构建会读取新配置。需要重启的是那些 JVM 层面的改动比如-Xmx堆大小、HTTP 端口、--prefix前缀、Jenkins 主版本升级、插件升级到不兼容版本等。简单记一下凡是启动参数和类加载层面产生变化的基本都要重启凡是在页面上有“保存”按钮的普通配置基本都不需要。6.2 插件也可以尽量不重启插件管理页面在安装插件时如果该插件支持动态加载会出现“部署”Deploy按钮点了之后 Jenkins 会在不重启的情况下把新插件加载进来。不支持的话会提示需要重启。早期 Jenkins 很多插件装完必须重启现在的版本已经好了很多。日常维护中如果团队对重启窗口没有太多容忍度一个实用习惯是把插件的安装/升级集中到版本升级的窗口里一起做不要今天装一个、明天升级一个。这样既减少重启次数也方便出问题时回溯是哪一次变更引起的。6.3 脚本控制台与 CLI想自动化重启的话脚本控制台/script是 Jenkins 管理员的“瑞士军刀”。在页面上打开脚本控制台执行jenkins.model.Jenkins.instance.restart()可以触发一次重启如果要安全重启可以先进入 safeRestart 模式或者通过 API 调用。这个手段我一般只在自己调试环境里用生产环境还是老老实实走服务命令因为脚本控制台没有任何二次确认敲错一行代码可能就直接把实例干掉了。它更适合用来做一些不重启就能改配置的动态调整比如临时修改系统属性。如果你想把重启操作脚本化用 Jenkins CLI 更合适。下载jenkins-cli.jar然后执行java -jar jenkins-cli.jar -s http://localhost:8080/ \ -auth admin:你的API_TOKEN restart需要安全重启时把最后的命令换成safe-restart。CLI 方式最大的价值在于可以写到运维脚本里比如发布流程里先排空队列再安全重启比人去点网页要可靠得多。需要注意新版 Jenkins 建议用 API Token 而不是明文密码来做认证安全策略比较严格的环境还会要求使用特定的 CLI 协议端口碰到连接失败先检查认证方式和端口配置。6.4 不重启的边界内存问题和插件冲突必须泼一盆冷水不重启不是万能的。服务跑久了堆内存碎片化、Full GC 频繁、某些插件持有旧类定义这些都是动态加载解决不了的。如果 Jenkins 已经出现明显的“卡、慢、假死”或者日志里有大量OutOfMemoryError该重启就重启别为了追求“零重启”把整个系统拖垮。减少重启频率的正确姿势不是硬扛而是做好基础维护控制插件数量及时清理废弃 Job合理设置 JVM 堆内存监控 JVM 指标发现问题早处理。这样即使偶尔重启影响也会小很多。我自己现在的工作流是日常配置改动基本不重启插件安装能动态加载就点部署升级核心或调整 JVM 参数时低峰期用systemctl restart jenkins如果页面还能打开但状态异常先试/safeRestart页面彻底打不开才考虑找 PID 杀进程手动拉起。最后提醒一句不管选哪种重启方式动手前先把$JENKINS_HOME的关键目录备份一份这个动作花不了两分钟但能救命的次数远比你想象中多。
返回列表