一次Jenkins出包机磁盘空间不足的解决记录

近日,Jenkins上的所有项目编译均失败,查Log,看到IOException: Disk full,便知出包机Mac的磁盘空间不足了。

这是一个非常诡异的现象,因为出包机总共有1TB的容量。我们的Jenkins策略会在构建前丢弃掉较旧的构建,以腾出磁盘空间,而且在构建前我们也会清空workspace下的artifacts目录,以保证上一次的构建不会有任何残留。 Alt text | center

出包机本身没有装与出包无关的其他大型软件,更没有音乐,图片和视频等大文件。鉴于出包机已连续工作了近两年,执行了上千次任务,可以断定磁盘空间被出包任务慢慢占满了。那么,到底谁是凶手?

找出真凶

第一感是打开系统的「关于」,查看磁盘的基本占用情况,可以发现有约700GB被一个叫「容器中的其他宗卷」所占据。毫无疑问,凶手就是这个「其他宗卷」。然而它是什么?在哪里?这些都不得而知。

这时,需要换一种思路:有没有一种方式知道占据磁盘空间最多的N个文件或目录?也许其他宗卷的内容就藏身于此。第一感还是打开了系统自带的Finder,但是除了找到几个大的安装文件外一无所获,仿佛这个其他宗卷被系统隐藏了一样。

这时候,命令行思维的优势便显现了出来,很多GUI没有实现的功能都可以通过命令行获得。在一番Google后,我找到了How to Find Biggest Files and Directories in Linux,里面详细介绍了在*nix系统下找到大文件的命令。

Alt text | center

在键入du -a | sort -n -r | head -n 20后,便出现了上图,我们可以发现./Libaray/Developer/Xcode/DerivedData占据了最多的空间,而事实便是这个目录确实占据了约700GB的磁盘空间。我们找到了真凶!

解决问题

DerivedData这个目录是做什么用的?

我们每次调用Xcode来构建代码时,Xcode便会在DerivedData目录下新建一个目录用来存放这次构建的中间过程文件。然而,在构建结束时,Xcode并不会删除它。所以在经历了上千次构建后,DerivedData目录就变得异常庞大。

由于DerivedData目录记录的是构建的中间过程,所以在每一次构建完成后,我们可以调用命令rm -rf /Users/Your_User_Name/Library/Developer/Xcode/DerivedData/*来将其删除(注意将Your_User_Name替换为真实的用户名)。

可是如果同时有多个iOS包要出的时候,我们不能简单粗暴的在每次构建完成后删除掉DerivedData,因为这样会影响其他还没有完成的构建。

我认为一个比较好的策略是定时删除,即选一个很小概率会发生构建的时间,执行一次删除命令。

具体步骤如下:

  1. 在Jenkins主页打开Manage Jenkins,然后打开Configure System,在环境变量里填下如下图红框所示的键值对。注意把值替换为你真实的DerivedData目录路径。
  2. Alt text | center
  3. 新建一个project,在构建里添加执行shell步骤,shell代码为rm -rf ${DerivedData}/*
  4. Alt text | center
  5. 我认为每周清理一次便可有效控制该目录的大小,周一早上5点通常是一个不会产生构建的时间点,在Build Triggers里勾选Build periodically,然后写入H 5 * * 1,这可以保证每周一的早上五点会执行删除任务。
  6. Alt text | center

真凶已伏法,从此,我相信出包机再次出现磁盘空间已满问题的概率将大幅度降低。

参考资料

发表评论

电子邮件地址不会被公开。 必填项已用*标注