Nodejs 不适用于大规模服务端开发?

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

今天看到文章 Node之父Ryan Dahl:我不想被定义。 前面是 Nodejs 之父 Ryan Dahl 的个人经历,耳熟能详,倒也没什么好说的。倒是中间这一段:

Node的非阻塞模型没有了多线程,但却多出了“回调地狱”问题。Ryan认为Node并不适合用来开发大规模的服务端应用,相比之下,Go语言会是更好的选择。而Node能够真正一展拳脚的地方是客户端。

看到这里不禁想,这下 Nodejs 社区该不会要炸了吧。果真,接下来就有一个 Node 粉在评论里抓狂了————当然,也仅此一个而已。

Nodejs 社区不可能看不到这个爆炸性的消息。但到目前为止,在国内主要的社区还看不到重量级的人物出来表态。或许正是因为这个消息太有冲击力,所以大家才不得不在发言之前慎之又慎吧。

Ryan 想要表达什么?

细看 Ryan 的发言,可以明白他的思想脉络是怎样的。当初之所以编写 Nodejs,是因为他相信基于多线程的并发模型并不是编写网络程序的正确方式,但 Nodejs 的回调模式虽然充分利用了资源,但异步回调的代码风格既不符合人类的一般思维习惯,维护起来也更加困难。而 Go 的解决方案则优雅得多:它既充分发挥了异步模式的性能优势,同时又把这种复杂性很好的隐藏在 Go routine 的背后,人们可以继续用清晰得多的同步风格编写代码。

Ryan 本人的总结是:对于大规模网络开发,他一定会选择 Go,而小型服务器用 Nodejs 是不错的选择。原话是这样的(引自 Node之父Ryan Dahl访谈录) :

我认为 Node 不是构建庞大服务器网络的最佳系统,我一定会用 Go 去做,这基本上是我离开 Node 的原因。实际上, Node 不是最好的服务器端系统。
我认为让 Node 真正发光的是客户端。例如,在建立网站时做一些脚本,捆绑客户端的 JavaScript。你可以在客户端和服务器端使用同样的语言。对一些比较小的服务器功能来说, Node 可能是正确的选择。但是如果你正在构建一个大规模分布式的 DNS 服务器,我不会选择 Node。

那么我理解,他的意思可能是这样的:对于小型应用来说,前后端使用相同的语言,在些基础设施、类库和代码方面有很多内容可以共享,同时也避免了切换语言在思维上的负担,对提升效率是有好处的。但对大型应用,前后端本身需要解决的问题规模就很庞大,Nodejs 作为粘合剂的作用就没那么明显了,而回调模式的问题在大量代码中会更加凸显,这时 Go 就有比较明显的优势了。当然,async/await 的异步方案可以在很大程度上缓解语法问题,但即便如此,和 Go 的并发模式比起来还是有差距的。

如何评价 Ryan 的表态?

我已经看到有人评价中称赞 Ryan 有勇气有个性,这一点我同意。但还有另一方面不知道有没有人注意到,Ryan 的发言中同时也表达了这样的意思:Nodejs 只是他创建的项目之一,他自己也没有对 Nodejs、甚至是 JavaScript 有特别的偏爱。这也是他“自黑”而无须有心理负担的重要原因之一。

说实话,我认为这才是合理的。作为一个了解很多语言和框架的编程老兵,所有东西无非是工具,不顺手,换过一把便是。完全没有必要对其中某一种过于执着或迷恋。即便是自己发明的,也应当一视同仁。本来这也是一个简单的道理,只是那些有语言狂热的人内心无法轻易接受罢了。还有那些在 Nodejs 上已经倾注了很多心血的人,即便在道理上能够明白,多少在心理上也会受到一定的冲击吧。

Ryan 的发言会对 Nodejs 和 Go 今后的走向产生何种影响?

实际上, Ryan 也表示了 Nodejs 用于小型项目是没有问题的。抛开程序员动辄奢谈“大型应用”的坏习惯不谈,事实上大部分程序员开发的应用系统应当都算是小型应用。即便在阿里腾讯这种体量的公司,大量程序员做的也只是其中庞大系统中很小的一部分,用了 Nodejs 就接着用,没有理由因为创始人的发言就换语言。特别是对于以全栈为目标的项目来说,Nodejs 应该是更加合理的选择。因为 Go 这种静态、编译型的语言,且有自己独特的工具链,对大部分前端来说参与的门槛太高了,而接受 Nodejs 则毫无压力。

对于 Go 而言,有 Google 这个强大的后台,这几年的发展本来就顺风顺水,当然目前还是小众语言,但以其年龄来说,比早期的语言已经算是火箭般窜升了。这次的事件毫无疑问会为 Go 带来又一波关注度。但我也在前面说了,Go 的语言特点对于前端程序员门槛太高; 对后端来说,Java,.Net 这些已成体系的社区缺乏足够转换的理由,倒是对于 C/C++ 和 Python 程序员可能有比较大的吸引力。但目前 C/C++ 和 Python 本身也比较松散,不大可能出现大规模的迁移。Docker 名义上算是 Go 的 Killer application,但本身是应用而非框架,并不足以说服开发者转向用 Go 开发。还有一点,Google 目前手中能打的语言在 Go 之外还有 Kotlin (虽然并不属于它) 和 Dart 等等,再加上 C++/Java/Python,战线已经拉的非常长,对于 Go 真正意义上的投入应该是有限的。 对于 Go 的未来,我还是持谨慎乐观的态度。

有趣的是,Nodejs 社区原著名程序员,众多 npm 库的作者 TJ 的去向也是离开 Nodejs 而转向 Go。两大精神领袖的去向都指向 Go,这是巧合?还是命运? Go 会是 Nodejs 的未来吗?

只有天知道。