Beyond What?——十年之后,谈谈 Ruby, Rails,过去和未来 (二)

版权声明:所有博客文章除特殊声明外均为原创,允许转载,但要求注明出处。

Beyond Java

上一篇文章 中,我们讲到了 Ruby / Rails 为何没有如先前人们预期的那样成为业界开发的主流——主要是在技术的层面上。但我觉得似乎还缺点什么。

有意思的是,Rails 当初之所以被当作 Java 的继承者,主要原因是在开发效率上有10倍的差距(撇开其中的宣传成分不论)。而之后被众多网站弃用,则是因为在性能上比后继者有10倍以上差距——这个变化当然有点讽刺意味,却也道出了一个事实:开发的风向已经变了。

多年以来,基于 Java 开发的应用系统,一直有一个金光闪闪的招牌,那就是“企业级开发”。拥有这个头衔似乎就是实力的证明,而一些Java开发者看向其他同行的目光,也不免会有点轻视的意思。而从我们今天看来,这些“企业级”系统中绝大多数无非是普通的 Web 三层应用罢了。至于部分开发者自以为的“分布式”架构,已经被 Martin Fowler 的分布第一定律所否定,只能认为是早期一次不太成功的实践。我们今天已经不太能听见人们拿“企业级”这个名号出来招摇了,因为早期人们自诩的高并发(其实绝大多数也就是几百到数千并发的水平),在今天动辄上亿 PV/UV 的互联网应用面前,简直连小儿科都算不上。

企业应用当然也有它的复杂性。这主要来源于各个企业自身复杂的商业规则和运行机制。但也同样如 Martin Fowler 所指出的,“业务逻辑最大的问题是没有逻辑”。要保证这些程序的正常运作,事实上并不需要多么强大的语言或框架作为基础,而考验的主要是负责人理清思路、规划结构的能力。而面对复杂多变的业务逻辑,轻装上阵、快速应变才是王道,静态语言在这个领域显得有点过“重”了。Java 在一个合适的时机出现,并占据了企业 Web 开发的主流,但从这些年的发展来看,能够在Web 领域大放光彩的,从 PHP、Rails 到 Nodejs,始终是动态语言的天下。

仅从语言本身特性而论,Ruby /Rails 是非常优美的,这也是多年前它能够折服一大批开发者的原因。但是为什么这些优点并没有让它真正成为时代的王者呢?上一篇文章从技术层面谈过了,但是人们仍然会追问(其实这也是 Java 当年面对的问题):Ruby / Rails 自身不能改变吗?不能克服这些缺点吗?是什么因素,使得开发者宁可放弃这个已经证明有很高生产力的语言/框架?

10倍效率提高当然美妙,但10倍服务器数量或者10倍内存占用可就绝不美妙了。这就是 Ruby / Rails 要面临的问题。事实上这个现象背后折射出几个现实:

第一,摩尔定律起作用的时代已经过去了。过去,无论程序写得多么低效,总有每年都在提升的CPU频率替它买单。但是目前单个 CPU 的密度已经提升到了极限,除非技术上有新的突破,否则程序已经在单 CPU 上已经无法跑得更快。“程序员的效率重于机器效率”这句名言,其实是建立在机器效率不断提高基础上的,当机器已经成为瓶颈时,单纯依赖机器的提升已经不够现实;

第二,真正的互联网应用来了,带来的是海量用户。对于企业应用来说,即便是低效的程序,支撑百十号人也并不在话下。但对于今天的互联网来说,上亿用户数量已经不是几个超级公司的专利,服务器维护成本成为许多互联网公司最大的开销,如果这个数字*10,确实让人无法接受。Google 就以各种千奇百怪的变态办法榨干服务器和网络性能而著称。低效的程序模型,在今天是后端程序的不可承受之重。

第三,高并发模型在今天很重要,但并不容易做到,特别是对于 Ruby 这种草根语言而言。今天人们大概不太会记得,当年从 DOS 的单进程进化到 Win2k 的真正抢占式多进程/线程,也花去了很多年时间,包括 C 标准库为支持多线程也必须进行大量修改,而早期很多程序在处理多线程时都存在莫名其妙的问题。今天,单纯的多线程机制已经不能满足高并发后端的需要,但已经存在的语言和库很难随之改变。Nodejs 因为这一点放弃了现有的、成熟的库,完全从一个全新的模型白手起家,才得以摆脱历史的桎梏。而 Go 和 Erlang 等也从设计之初就以高并发作为目标。Java / .Net 则改变的有点困难,好在它们都有有钱的爹,可以投入大量时间成本去改造虚拟机,支持新的并发范式。在这个过程中最吃亏的是 Python / Ruby 这样的草根:它们已经存在大量程序和库,很难快速迁移到新的模型;而修改解释器或虚拟机又是个极其艰巨的工作。Python / Ruby 语言中存在一些长久以来的问题,这一点社区和作者都非常清楚,但无奈没有足够能力去改造(Python 的 GIL 看起来要永久存在下去了)。

上面说到 Python 和 Ruby,这又是一个有意思的话题。 Python 和 Ruby 同为动态语言,历史之久也相去不远,但在具体的设计风格、发展方式上又大相径庭,以至于很多时候会拿来做比较。Python 其实成名比 Ruby 更早,应用范围也比 Ruby 更广,但可能也是这个原因,造成整个社区比较分散,缺少 Ruby 社区像 DHH 这样的领军人物和 Rails 级别的杀手级引用,始终处在一种既红不起来、又不至于被人彻底遗忘的中间状态。Python 把自己定位成胶水语言,胶水当然不能成为当红炸子鸡,但始终有一定的存在感,应该说 Python 的未来相当长时间内至少是不会掉队的。而 Ruby 虽然因为 Rails 一飞冲天,但除此之外始终没有找到新的突破口,当 Rails 难以继续担当 Web 旗手时,整个社区的未来也就令人担忧了。这样说可能令 Ruby 开发者不太舒服,我也不认为 Ruby 会从此销声匿迹;但现实就是,Ruby 的部分语言特点已经被别人学走,在生产力上不再有以前那样具有压倒性的优势,在应用方面则找不到新的杀手级场景。它在今天确实已经不再有明显的号召力。

说了那么多 Ruby ,我想回头回头说说 Java。这个语言在早期曾经走过很长的弯路,包括在基础类库的不合理、企业模型上的失败设计、过重的语法,一直到今天还在艰难的纠正。但它确实留下了一笔宝贵、其他语言无法相比的巨大财富,这就是一个优秀的社区和了不起的旗手。其实这个社区名义上的领导者(从 Sun 到 Oracle)从普遍的观点来看一直是不合格的,但它们做出了一个了不起的决策,让社区有能力自我纠正、自我改造。J2EE/EJB 设计不良,就有人出来呼吁 without EJB;JDBC 不好用,就有人开发 Hibernate;官方搞不出好的 IDE,有社区和商业团体开发的 Eclipse /NetBeans / IntelliJ 顶上。而众多优秀的开发思想包括敏捷、精益、重构、持续集成、SCRUM等也是在这个社区发展起来的——虽然这些思想并不依赖于特定的语言,不过Java为它们提供了主要的实践沃土,则是不争的事实。而像 Tate 这样的人物,在 Java 如日中天,自己也在靠着 Java 谋生的背景下,有勇气面向社区说出:新的浪潮已经到来,Java 之后会有下一代技术兴起。这种气魄和胸怀也令人敬佩。尽管我个人认为今天 Java 不再是应用领域的最佳选择,不过并不妨碍我向这些前辈表达我的敬意。