今晚在 Twitter 上和 @tualarix 聊起了 Go,心血来潮想写一个 Web 框架的回顾,于是选了一些我用的比较多的 Web 框架来逼逼一番。
聊 Web 框架之前,我们还是要先达成一个共识,就是没有什么框架是银弹,可以搞定所有问题,只有最适合你当前业务的框架和语言。
而作为一个开发者,片面的信仰任何一种技术都是不负责任的,因此这篇文章,目的不是比谁最牛逼,而是谈谈这些框架都好玩在什么地方。
2011 年我开始用 RoR 和 MongoDB 来构建 Piner(基于计划的社交软件)的后端,Rails 最大的魅力就是 Convention over configuration 约定优于配置这种敏捷开发的理念。
举个例子来说,你要买一个包子,如果你不说你要什么馅的,那么包子店就随便给你一个包子,因为此时的重点不是包子馅,而是包子本身,一个由皮,馅构成,由蒸这种加工工艺做成的点心,这就是约定。而当你指定要什么馅的时候,就成了配置。
当应用到 Rails 里是什么样呢?
我们再来举个例子,比如你想要开发一个博客,你只需要告诉 Rails 你需要一个博客,那么 Rails 就会自动帮你生成代码,因为常规的博客功能就是约定。当然,你也可以用参数指定博客的具体细节来配置它。
这种理念,让完全小白的我像看魔法一样爱上了它,若干年后我回想起来也还觉得,新手更应该用 Rails,因为当你什么都不懂的时候,Rails 可以保证你不犯太低级的错误,安全有保障,效率也很高。而当你开始想了解内部的实现的时候,学到的也是最科学的 Web 框架设计理念,这也无外乎 Rails 社区像 Web 框架的黄埔军校一样,离开的社区成员随手就创造了 Node.js Elixir 这些框架。
Rails 尽管很有趣,最大的瓶颈也就是执行速度,而 Ruby 语言本身也没有良好的多核计算支持。但对于早期项目来说,这是最好的选择。
2014 年开发 CatchChat 的后端的时候,我脑子一抽觉得 Node.js 被传的这么快,无阻塞设计这么牛逼我应该用这个来做。后来事实证明它确实很快,但是有几个问题是很棘手的。
除了快之外,Node.js 最大的问题是不稳定,他有着像 Rails 一样优秀的开发效率,却远远不如 Rails 稳定,JavaScript 语言本身也不够好用,还有一些容易踩到的语言层面的坑(当时我竟然没有用 lodash 这类的东西,直接裸写 JavaScript)
在 Node.js 上,我最终学到的一件事情是,语言速度快这些特性并不能解决高并发这种场景,因为在那个时候,服务器的性能瓶颈不是语言,而是数据库。
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 的历史问题,他一直都不流行,因此并没有很多好用的轮子,但假以时日,谁知道呢。
最初学 Python 的时候我觉得不编译真的是太爽了,但直到用 Go 写 Server 的时候,我才觉得编译好爽。
Go 不光编译的快,运行起来也是非常快,强大的协程同样天生支持高并发,多核利用。再也不需要像 Node.js 或者 Ruby 这样纠结语言的速度。
Rails 也好, elixir 也好,部署到服务器得搞一堆依赖安装到服务器上,Go 全部依赖编译成一个二进制包上传到服务器就好了,你的服务器可以只有一个文件。
小型的业务跑起来只有 400KB 的内存占用,这也就只会发生在编译型语言上。
但 Go 并没有一个统治型的 Web 框架出现,使得你可能有点选择困难,但前后端分离在这一点上让我们变的幸运了,如果只是做个 API Server,你真心不需要什么复杂的 Web 框架。
Go 对我来说最大的缺点,就是写起来和 C 语言一样无聊。
Swift 相比 Go 而言,缺少语言层面的并发和异步支持,没有成功案例,也没有成熟的 Web 框架,但是为什么我最期待呢?
因为他有像 Rails 一样强大的社区,有像 Ruby 一样有趣的语言,有像 Go 一样编译语言的优秀特性。
但就目前来看,语言层面的并发和异步特性估计要到 2018 年才能用到,所以,大家还是玩玩 Go 和 elixir 吧……