流利说为什么要从 Ruby 转到 Elixir

可能有些同学知道我最近都在搞 Elixir,基本除了工作时间,都在写 Elixir,不管是博客还是 GitHub,都是 Elixir 的痕迹。虽然写的挺愉快的,收获也很多,但还是有些遗憾的是,不能真正用到生产当中去。当一个工具没有办法真正在线上使用时,你永远也无法知道它的坑点与优点。也有很多人问,流利说用 Elixir 吗,我总是尴尬的说,目前还没有,但将来说不定会呢。

没想到,将来来的那么快。我作为公司内部比较早期深入接触 Elixir 的开发者,想来聊一聊为什么我们要从 Ruby 转到 Elixir,这并不是一时兴起做的决定,而是在长期使用 Ruby 的经验上,又加上对 Elixir 的研究和使用所做的决定。

提到这个话题,可能第一个想到的原因就是速度。因为众所周知,Ruby 很慢,而 Elixir 是基于 BEAM(Erlang 虚拟机)的,性能上要比 Ruby 快出不少。Erlang 基于 Actor 模型,虚拟机内部有自己的轻量级进程,都能够让并发编程变得很容易。而且对于分布式的架构,Erlang 也能够处理得很好。Erlang 的 OTP 也让我们能更好地做并发编程,并且帮我们处理 Erlang 进程的监控和重启等基本工作。

似乎 Ruby 圈子的开发者很多都觉得,性能嘛,没那么重要,以后优化就行。但我们现在觉得,性能对我们至关重要。很巧,Instagram 最近发的一篇博客,最后也提到说他们 performance 提高之后,用户数据也变好了。虽然我们现在的量级也许不是很大,但我们的野心还是很大的,所以性能问题对我们的影响力会越来越大,与其之后再去解决这个问题,不如现在开始做准备。另外,现在硬件发展的很快,几十个甚至上百个核的服务器都司空见惯,使用 Elixir 能够更好的利用这些机器,为我们节省更多成本。

虽然性能很重要,但是如果只是为了性能而换一个语言、一个技术栈,还是很难决定的一件事的。而且其他语言性能也很不错,比如 Go,但为什么偏偏选了 Elixir 呢?

可以说,几乎是必然的选择。

首先,两者的语法很像,这使得其他 Ruby 开发者也能够很快适应,并开始用 Elixir 来工作。我个人觉得语法是很重要的一个东西,毕竟是你每天要面对的东西,就像是一个人的脸面一样。而且语法也代表着这个语言的个性,相信很多人可能是因为 Ruby 的语法而喜欢上 Ruby 的。Elixir 的作者是原先 Ruby 社区的大牛,自然不可避免地受到很多 Ruby 的影响。除了像之外,Elixir 还有很多自己的个性,比如 |> 这个符号,就简化了很多嵌套的调用。

虽然像 Ruby,但其实 Elixir 骨子里却是 Erlang。比如我个人很喜欢的 pattern matching,能够让你的代码流畅很多。用习惯了之后,再换回其他没有 pattern matching 的语言,简直是一种折磨。

而且 Elixir 是函数式的,这点其实很重要。与其说函数式是一种语言模式,不如说函数式是一种思想,即便是一般的语言和可以写的像函数式一样。函数式会教你需要减小函数的副作用,从而让代码和测试的编写都变得很容易。没有了面向对象的复杂性,只靠数据和函数,能够让逻辑代码变得更加清晰易懂。特别是当项目变得越来越大时,函数式的代码会更加容易维护。

除了 Elixir 语言层面的东西,Elixir 整个生态系统也非常出色,不管是包管理的 hexmix 等各种工具链,还是第三方的库。

大家经常会把 PhoenixEcto 和 Rails、ActiveRecord 做对比。我可以负责任地说 Phoenix、Ecto 绝不比 Rails、ActiveRecord 差,甚至很多方面做的更好。虽然有点像,但很多设计思想却很不一样。比如 Phoenix 虽然也有很多约定,但整体却更透明,更容易配置,而且借助 Erlang,它对于实时通信、长连接能够处理的更好。在未来,实时肯定是趋势,毕竟现在的 HTTP 请求方式只是受限于过去硬件而已。

而相比于 ActiveRecord 把 model 层和数据层耦合在一起的做法,Ecto 是完全分开的,在一些场景下 Ecto 能处理的更好。比如,如果你要把 Model 跟不同的 DB 关联起来,AR 里你可能需要去查很多资料,还不确定是否靠谱。但 Ecto 几乎是自身直接支持的,因为二者是分离的。AR 调用方法就能直接做查询的做法,在项目后期简直是一种灾难,稍不注意就会写出慢的代码,而你很难控制所有人写的代码都没有问题。但 Ecto 却能够让你减少很多这样的影响。

Ruby 经常被人称道的是开发效率很高,但Elixir 也是绝对不输 Ruby 的。而且 Ruby 的项目经常到后期的开发效率会降下来,但由于上边提到以及未提到的特性,Elixir 项目到后期也更容易维护。

最后一个问题,在现在公司、产品都快速发展的时候,选择换技术栈,是不是一个好的决定? 我只能说没有对错,因为无法做 AB test,比较换或不换之后几年的结果,只能说这是一个选择。但我相信,这个选择不会让我们后悔。

我们会先在内部项目中使用 Elixir,没问题之后,会用 Elixir 来写主项目的新 feature,然后再把过去的代码一点点换掉。

如果你对我们的产品和我们做的事情感兴趣,欢迎投递简历或者直接联系我。也欢迎和我们交流。

 
69
Kudos
 
69
Kudos

Now read this

How does Plug work with Cowboy?

Plug的文档里有个通过Plug写应用程序的简单例子: defmodule MyPlug do import Plug.Conn def init(options) do # initialize options options end def call(conn, _opts) do conn |> put_resp_content_type("text/plain") |> send_resp(200, "Hello world") end end #... Continue →