nettyElm前置

为什么要学Elixir和Phoenix

2020-07-01  本文已影响0人  轻触未来

原文 why_elixir

好多年前,经Erlang之父Joe的一篇文章认识了Elixir elixir一周
当时感觉语法比Erlang稍显罗嗦,除了管道让人眼前一亮,具有威力巨大的宏的之外,没有太多感受,也没有深入研究。
前些日志,偶然发现了Phoenix liveview,引起了巨大兴趣。详细了解才发现,Elixir/Phoenix生态已经完善到了如此地步。
看了好些相关的文章,这篇文章和我的感受差不多,记录一下。

为什么是Elixir和Phoenix

假设RoR是你默认的后端技术。为什么会使用新的Elixir和Phoenix框架呢?

其中一个原因是软件工程逐步转移到函数式、并发友好的语言。使用(具有这些特性)Elixir语言,你将更胜任手头的工作;Elixir还有一些独特的属性使得她非常适合web开发,也包括其他一些用途。

特性

可靠性

没错,Elixir是一个非常新的语言。这可以使你认为这个语言不是非常可靠。但是总的来说Elixir是一个Erlang虚拟机的友好接口罢了。

Erlang从上个世纪80年代
就开始被用来创建一些非常可靠的系统。Erlang被用来运行电话系统。电话系统如果不工作可要命了。

所以Erlang的创造者就创建了一门几乎不死机
的语言策略来运行复杂的系统。这些策略包括系统中多层级的监督者进程,当遇到错误的时候重启进程。当微服务广为人知之前他们已经在用微服务了。

并且因为他们要把服务运行在很多电话交换机上,他们就发明了并行运行代码的非常棒的模型。

虽然非常新,Elixir继承了Erlang语言的所有优势,并且提供了更加友好的语法和工具。

并发

近年来,CPU频率提升已经不大。但是CPU核心数却是越来越多。这就要求软件系统能够更具并发来适应硬件系统的发展——这就意味着系统的不同部分并行运行在不同的核心上。

并发代码的主要问题就是竞态问题,导致非预期的结果。OO语言如Ruby不能很好地解决类似问题。但是函数式语言,如Elixir,可以解决类似问题。用Elixir编写并发代码非常简单,并且基本不可能影响同时运行的其他代码。

在Ruby中,我们从不会问“我能够创建另外一个对象吗?” Ruby的一切都是对象,并且创建对象的代价很小。我们想创建多少就创建多少。

在Elixir中,进程就像对象——我们可以创建数以千计的进程,同时运行,并且从不用关心他们。这个能力简化了我们在Ruby中很多难题。

简单

当我们写Rails应用时,需要依赖很多其他组件。

Rails应用同一个时刻只能处理一个web请求,并且我们不能在需要时新创建进程,因此我们不得不在web服务前面应用Ngnix来处理并发请求然后创建多个应用服务器实例来处理并发请求。

我们不能在不阻塞web请求的情况下处理后台慢任务,因此我们不得不添加redis和队列来处理后台任务。

我们不能用珍贵的进程来维持用户连接,因此我们不得不添加推服务来增加实时功能。

我们不能让一个大的Ruby进程一直处理定时任务,因此我们不得不增加cron

我们没有内置的Ruby工具来管理系统运行中的多个部分,因此我们只能使用foreman
god
等来启动和监控系统。

在Elixir中,我们可以根据需要创建几乎无穷多个进程,因此我们可以(理论上)放弃所有这些工具。

Elixir代码也比OO代码更容易理解,因为他们更明确。

Functional programming is associated with concurrency but it was not by design. It just happens that, by making the complex parts of our system explicit, solving more complicated issues like concurrency becomes much simpler." - Jose Valim

性能

Phoenix web框架的性能比Rails高多了。这个例子显示Phoenix性能(比Rails)高出10倍。而且Phoenix服务器的负载更低——Rails更倾向于预处理请求。这会导致“链式响应”,因为Rails应用配置为只有固定数量的应用进程,因此如果有些进程慢了,会导致其他请求不得不等待,因此显著增加了响应时间。

更多的,不用缓存的Phoenix应用比用了缓存的Ruby应用性能更高。这点很重要的原因是缓存极大的增加了系统地方复杂性和错误,并且缓存也不是时时有效的;根据Bleacher Report提供的数据显示,(他们使用Phoenix开发的系统)支持处理250K并发用户的新闻和推特。根据a talk their developers gave,他们的服务器从100个AWS缩减到了5个,cpu负载很少超过10%,并且性能比原来的Rails实现高出10多倍。

Phoenix比Rails性能更高、内存更少的其中一个原因就是Erlang虚拟机处理string IO的方式。一个Erlang web框架是这样描述的

Erlang Respects Your RAM! Erlang is different from other platforms because when rendering a server-side template, it doesn't create a separate copy of a web page in memory for each connected client. Instead, it constructs pointers to the same pieces of immutable memory across multiple requests. So if two people request two different profile pages at the same time, they're actually sent the same chunks of memory for the header, footer, and other shared template snippets. The result is a server that can construct complex, uncached web pages for hundreds of users per second without breaking a sweat. With Erlang, you can run a website on a fraction of the hardware that Ruby and the JVM require, saving you money and operational headaches.

我的这篇文章 细节

更多的公司开始使用Elixir——比如Pinterest所说

So, we like Elixir and have seen some pretty big wins with it. The system that manages rate limits for both the Pinterest API and Ads API is built in Elixir. Its 50 percent response time is around 500 microseconds with a 90 percent response time of 800 microseconds. Yes, microseconds. We’ve also seen an improvement in code clarity. We’re converting our notifications system from Java to Elixir. The Java version used an Actor system and weighed in at around 10,000 lines of code. The new Elixir system has shrunk this to around 1000 lines. The Elixir based system is also faster and more consistent than the Java one and runs on half the number of servers.

伸缩性

Erlang虚拟机的并发模型非常适合多核cpu,但是在多核cpu发明之前虚拟机就存在了。她的原始目的是通过在多个不同机器上运行来支持并发和容错。

这就使得她提供了非常优秀的工具来创建轻松处理非常大的负载的系统,并且能够非常容易地增加服务器。

就如Erlang web服务器文档所说:

At the time of writing there are application servers written in Erlang that can handle more than two million connections on a single server in a real production application, with spare memory and CPU!
The Web is concurrent, and Erlang is a language designed for concurrency, so it is a perfect match.
Of course, various platforms need to scale beyond a few million connections. This is where Erlang's built-in distribution mechanisms come in. If one server isn't enough, add more! Erlang allows you to use the same code for talking to local processes or to processes in other parts of your cluster, which means you can scale very quickly if the need arises.

灵活性

使用Elixir和Phoenix打开了一扇创建应用的大门,这些是使用RoR不能达到的。

Phoenix框架通过websockets(或者polling,作为降级方案)提供了实时通信功能。在基准测试中,单台服务器支持2百万持续链接!同时,他们也开发了支持iOS、Android和C#(视窗设备)本地channels客户端。有了这些支持,你可以轻松创建出聊天应用、网络游戏和更多其他的应用。

Elixir还可以用在嵌入式设备如Nerves。这对于Ruby来说是不可想象的(即使有mruby)。

Correctness

Rails的ActiveRecord鼓励开发者在应用代码中做所有的数据检查。但是,依赖数据库状态的检查只能依赖数据库,用约束或者锁。这些包括:

Rails应用使用这些约束是可能的,但是是非典型应用,工具也不建议使用这些约束。

Elixir的Ecto数据库工具拥抱这些约束,也有内建的添加约束、捕获约束检查、返回用户友好的错误信息的支持。实际上,你不得不做一些如唯一性检查的工作(译者注:这句话不太理解)。

结论

适合做的事

真的,任何Rails适合做的事情,Phoenix都合适做。

但是如果你的应用有如下特点的话,Phoenix最适合不过了:

上一篇下一篇

猜你喜欢

热点阅读