回顾过去用过的 Web 框架

今晚在 Twitter 上和 @tualarix 聊起了 Go,心血来潮想写一个 Web 框架的回顾,于是选了一些我用的比较多的 Web 框架来逼逼一番。

聊 Web 框架之前,我们还是要先达成一个共识,就是没有什么框架是银弹,可以搞定所有问题,只有最适合你当前业务的框架和语言。

而作为一个开发者,片面的信仰任何一种技术都是不负责任的,因此这篇文章,目的不是比谁最牛逼,而是谈谈这些框架都好玩在什么地方。

Ruby on Rails 是效率的极致

2011 年我开始用 RoR 和 MongoDB 来构建 Piner(基于计划的社交软件)的后端,Rails 最大的魅力就是 Convention over configuration 约定优于配置这种敏捷开发的理念。

举个例子来说,你要买一个包子,如果你不说你要什么馅的,那么包子店就随便给你一个包子,因为此时的重点不是包子馅,而是包子本身,一个由皮,馅构成,由蒸这种加工工艺做成的点心,这就是约定。而当你指定要什么馅的时候,就成了配置。

当应用到 Rails 里是什么样呢?

我们再来举个例子,比如你想要开发一个博客,你只需要告诉 Rails 你需要一个博客,那么 Rails 就会自动帮你生成代码,因为常规的博客功能就是约定。当然,你也可以用参数指定博客的具体细节来配置它。

这种理念,让完全小白的我像看魔法一样爱上了它,若干年后我回想起来也还觉得,新手更应该用 Rails,因为当你什么都不懂的时候,Rails 可以保证你不犯太低级的错误,安全有保障,效率也很高。而当你开始想了解内部的实现的时候,学到的也是最科学的 Web 框架设计理念,这也无外乎 Rails 社区像 Web 框架的黄埔军校一样,离开的社区成员随手就创造了 Node.js Elixir 这些框架。

Rails 尽管很有趣,最大的瓶颈也就是执行速度,而 Ruby 语言本身也没有良好的多核计算支持。但对于早期项目来说,这是最好的选择。

Node.js 除了快之外?

2014 年开发 CatchChat 的后端的时候,我脑子一抽觉得 Node.js 被传的这么快,无阻塞设计这么牛逼我应该用这个来做。后来事实证明它确实很快,但是有几个问题是很棘手的。

除了快之外,Node.js 最大的问题是不稳定,他有着像 Rails 一样优秀的开发效率,却远远不如 Rails 稳定,JavaScript 语言本身也不够好用,还有一些容易踩到的语言层面的坑(当时我竟然没有用 lodash 这类的东西,直接裸写 JavaScript)

在 Node.js 上,我最终学到的一件事情是,语言速度快这些特性并不能解决高并发这种场景,因为在那个时候,服务器的性能瓶颈不是语言,而是数据库。

elixir 除了太早期,几乎没有缺点

elixir 是我去年年底开始尝试的一门语言,他是 Rails 社区的开发者出来基于 Erlang 搞得二代语言。

而 Erlang 是 1987 年爱立信发布的针对电信手机通讯的语言,天生支持高并发和高 uptime,在移动互联网的著名成功案例就是 Whatsapp,单个机器可以支持 200 万连接。

elixir 是一个完全函数式的编程世界,他的哲学非常有趣,认为数据就是从管道的一端流到另一端,同一个内存地址上数据不应该被改变(除了被 GC 清除)。

用一个例子来说明吧

a = 1
a = 2

第一行,elixir 在内存分了一块地址,赋值为 1,并把 a 指向了这个内存地址,在第二行,elixir 会重新分配了一个内存地址,并赋值为 2,然后把 a 指向了新的地址,而不是改写了原本 1 所在的那个内存地址的值。

上面这个写法在 elixir 的世界也是错误的,正确的写法应该是

a1 = 1
a2 = 2

因为在 elixir 里, = 号其实并不是赋值的意思,而是 match.

除此之外,elixir 还有很多非常酷的概念,它的概念会让你觉得啊原来编程还可以这样想,因此,我比其他任何框架都更推荐你使用 elixir 的 Phoenix.

elixir 也有一个比较尴尬的问题,也算 erlang 的历史问题,他一直都不流行,因此并没有很多好用的轮子,但假以时日,谁知道呢。

Go 让我有点爱上了编译

最初学 Python 的时候我觉得不编译真的是太爽了,但直到用 Go 写 Server 的时候,我才觉得编译好爽。

Go 不光编译的快,运行起来也是非常快,强大的协程同样天生支持高并发,多核利用。再也不需要像 Node.js 或者 Ruby 这样纠结语言的速度。

干净

Rails 也好, elixir 也好,部署到服务器得搞一堆依赖安装到服务器上,Go 全部依赖编译成一个二进制包上传到服务器就好了,你的服务器可以只有一个文件。

小型的业务跑起来只有 400KB 的内存占用,这也就只会发生在编译型语言上。

但 Go 并没有一个统治型的 Web 框架出现,使得你可能有点选择困难,但前后端分离在这一点上让我们变的幸运了,如果只是做个 API Server,你真心不需要什么复杂的 Web 框架。

Go 对我来说最大的缺点,就是写起来和 C 语言一样无聊。

Swift 我最期待的语言

Swift 相比 Go 而言,缺少语言层面的并发和异步支持,没有成功案例,也没有成熟的 Web 框架,但是为什么我最期待呢?

因为他有像 Rails 一样强大的社区,有像 Ruby 一样有趣的语言,有像 Go 一样编译语言的优秀特性。

但就目前来看,语言层面的并发和异步特性估计要到 2018 年才能用到,所以,大家还是玩玩 Go 和 elixir 吧……