写在前面:我使用 Archlinux 已经快三年了,而且最近两年中它已经是我的主系统,工作、娱乐都是用它完成的, Windows 只是用来刷刷 BIOS ……我个人还是很喜欢 Archlinux 的 KISS 哲学的,软件包时刻跟随上游并且保持原汁原味,滚动更新随时体验新特性,最喜欢的大概还是 Arch User Repository 了吧……说了这么多,其实核心意思只有一个——我不是什么 Archlinux 黑,我个人一直都在用它,只是客观地陈述它绝非“银弹”或什么“最好的发行版”,它有它适合的对象和环境,而这绝不包括“生产服务器”!

滚动更新?先做好 QA 再说!

唔这儿的 QA 不是 Q&A 而是指 Quality Assurance 。一个发行版绝不只是把上游的源代码收集、打包就完事儿了,如果这么弄完压根就启动不起来、动不动 Kernel Panic 、软件包依赖混乱甚至死循环……那这肯定不能算是一个能用的“发行版”。避免这些问题的方法就是所谓的质量保证,包括完善的多阶段测试、 bug tracker 等等。发行版在基本奠定了技术基础之后(主要是包管理器、自动构建系统等等),绝大部分时间都是花费在软件包的维护、测试之上,各大发行版也是上游软件的主要 bug reporters (某些重量级团队还是代码贡献者)。

Archlinux 也并非完全没有测试,它也有自己的 testing 分支和完善的 tracking system 。然而由于 Archlinux 的哲学,更新速度非常之快,甚至 GNOME 2 到 3 这样的大型更新它都只用了不到一个月就正式发布了。而 Archlinux 毕竟不算是一个大型发行版,工作人员有限,这么短的时间之内很难进行彻底的测试。发布之后再遇到大小 bug 都是再常见不过的事情,除了一般软件 bug 甚至还有内核和硬件之间的兼容问题……比如我的上一篇博客就提到了两个相当严重的 bug 。想看更多的例子?去官方论坛看看就知道了。

由于 Archlinux 的特点和哲学,其实这不是什么大问题。折腾 Archlinux 的都不是小白,在社区的配合之下一般最后都能顺利找到问题根源(大多数时候是上游 bug ……)然后找到 workaround 并向上游反馈。包括我在内的不少用户其实是乐在其中的(虽然嘴上抱怨不断)。 Archlinux 的“用户”在一些大型发行版里其实应该是“志愿者”之类的存在……

但这在生产环境之下是不能容忍的。你让一个生产服务器更新之后遇到 bug 然后运维顶着上司压力满头大汗地找问题、提 issue ?对这一点抱有疑问的人一定没有在商业公司做过运维。不要和我说什么你的个人博客 VPS 用的是 Archlinux 。

更新内核后竟一定要重启?

这应该是 Archlinux 最大的问题了。很多 Linux 用户都不理解为何 Debian 和红帽系都要把每个内核版本分开打包,然后再做一个虚包指向最新版内核,更新内核时不会自动删掉旧版本,还得之后手动删除……

这其实是有非常重要的理由,而且不限于是“保险起见”,新内核启动不起来的时候可以选择旧内核。更重要的原因是—— Linux Kernel 是模块式的、动态加载的,而 /usr/lib/modules/LINUX-KERNEL 是属于内核软件包的。如果在更新内核的时候删掉了旧版内核的软件包(也就删掉了模块目录),就会使得还未加载的模块无法再被加载了。觉得没有影响?那么我告诉你——硬件驱动都是以内核模块形式存在的。举个例子,如果你使用 Archlinux ,在某此启动之后都没有插过 U 盘,然后更新了内核,你就发现 U 盘插进去以后怎么都认不出来(USB EHCI 模块和 vfat 文件系统模块都没挂载……)。你说服务器上不会有硬件变动?那么你一定是忘记了 OpenVPN 之类的软件,在启动之后需要建立一个虚拟设备(比如 OpenVPN 的 TAP 或者 TUN ),如此一来也就无法使用了。

最终的结果就是,使用 Archlinux ,要么你就别更新内核,要么更新了内核以后就立即重启以免遇到奇怪的问题。这种粗暴的更新方式难道不是比 Windows Update 还要糟糕么?(用过 Windows Server 的人一定遇到过更新以后要求你重启,甚至如果你正好处于一个活跃会话,那么如果你不立即取消掉那个对话框, 15 分钟后就直接给你重启了……)

糟糕的 Pacman

比起复杂甚至臃肿的 yum/rpm 和 apt-get/dkpg , Archlinux 的包管理器要简单许多,一个 pacman 就搞定了“源”和“包”两头,完成了别的发行版两个软件才能做到的事情。

可如果真要是这么简单的一个程序就能做好的事情,为什么别的发行版都要这么“笨”地开发如此复杂的工具?答案其实很简单——软件包管理本来就是非常复杂的事情。我不是一个包管理者,在这方面没有什么发言权,但单从一个用户角度来看也足够意识到其存在的不足了。依赖、推荐不够灵活,只有 depends opt-depends suggestions 三种,缺乏“虚包”的支持。一些常见的需求比较难以优雅地实现,比如:一个软件有多个不同的实现时,只能通过设置相同的 provides 然后再互相 conflicts 实现,这样一来每加一个新的实现就要修改之前所有的相同 provides 的包,而且也缺乏 dpkg-reconfigure 之类的工具来选择一个虚包到底使用哪一个实包从而实现灵活地在不同实现之间切换的功能(比如 Oracle JDK 和 OpenJDK 之间的切换,在 Archlinux 里只能安装一个然后删除掉另一个)。

另外, Archlinux 的打包粒度太大(比如一个 php 包就包括了大量非必须模块,得靠修改配置文件来启用或禁用,而在 Debian 和红帽里则是被拆成了很多个包)。当然,也有人认为 Debian 的粒度太细就是了。不过就我两年的使用经历看来 Archlinux 的包的确偏大,对于桌面版没有什么问题,这年头大家的硬盘也都挺大,但在服务器上一般都是希望安装尽可能少的软件以尽可能减少漏洞和 bug 。

当然,比较简单的包管理器也有一个好处,就是降低了打包的门槛。这也是 AUR 能够这么方便易用、内容丰富的部分原因。

最后,吐槽一下 pacman 不会自动清理包缓存,哪怕是很早以前的。我在用了两年之后包缓存有30多个G,直接把我的根分区都占满了……