欢迎来到我们关于公司在生产中使用Elixir的系列案例研究。请看我们到目前为止发布的所有案例。
Heroku提供服务和工具来构建、运行和扩展网络应用。他们使开发人员和团队能够专注于他们的应用程序的设计和工艺。Heroku早在2007年就开始开发,专注于Ruby编程语言,从那时起,他们已经扩展到支持多种运行时,无论是正式的还是通过构建包。
随着平台的发展,他们的工程团队也采用了不同的语言,其中之一就是Elixir。在这篇文章中,我们将讨论Heroku的两个不同的工程团队,即前端团队和Vault团队,是如何采用Elixir的。
使用Elixir的第一步
Vault团队是第一个在Heroku内部使用Elixir的团队。他们的团队负责许可和金融服务,如开具发票、信用卡支付等。他们的大部分服务是在Heroku内部使用的。
他们不得不重写他们现有的一个服务,这是给Elixir一个完美的尝试机会,因为该服务的困难和风险大多是已知的。实验是成功的:他们在生产中部署并运行了他们的第一个Elixir应用程序。这为越来越多地使用Elixir铺平了道路。
后来,他们遇到了一个新的挑战:他们必须审计大量的数据,而根据经验,他们知道Ruby的实现需要太长时间才能完成。鉴于他们已经在加紧熟悉Elixir,他们选择应用Elixir的GenStage来解决这个问题,这是一个用于数据处理的低级库,而这只花了几个小时。从这一刻起,他们就对这种语言和平台产生了兴趣。
用Elixir解决操作复杂性问题
前端团队也有类似的故事:他们首先使用Elixir来解决一个很好理解的问题,然后从那里开始推进。
前端工程师负责维护所有的用户界面:CLI、仪表盘,以及一堆与数据打交道的后端服务。他们为Heroku客户提供的功能之一是分析。
起初,他们将分析结果发送到Mixpanel。然而,由于跨域问题,他们在获取数据时遇到了一些问题,于是他们决定用内部的Elixir服务取代Mixpanel。该服务使用Plug,一个用于构建网络应用程序的库,并有一个单一的端点。
我们在这方面有很多乐趣,也有很多运气,所以我们继续这样做。
- 首席工程师Micah Woods,关于迁移到Elixir。
后来,他们花了一年多的时间专注于运营的稳定性,在此期间,他们开始将部分Node.js微服务重写成Elixir。今天,他们已经将他们众多的Node.js微服务迁移到一个主要的Elixir应用程序中,并有一个辅助服务用于认证。事实上,Elixir能够处理他们所提出的一切,加上他们对Erlang稳定性的经验--Heroku的路由器使用Erlang--使他们能够大大简化操作。
生产力和可扩展性
前端团队使用Elixir已经两年了。该团队有21名工程师:其中大约4名全职做Elixir,总共有8名工程师在这里和那里做Elixir。
他们用Elixir建立的第一个服务,即分析服务,接收请求并将其放入内存队列,在同一虚拟机内进行处理。它每秒钟处理大约3千到4千个请求。99%的响应时间保持在0-1毫秒内,偶尔也有4毫秒。他们使用3个Heroku dynos进行容错--当然,Heroku使用Heroku作为他们自己的基础设施。
主要的Elixir应用程序使用Phoenix网络框架来驱动Heroku仪表板,通过WebSockets提供实时功能,并支持其他服务。这个应用程序运行在5个Heroku的dynos上--尽管他们的工程团队认为他们可能可以用更少的时间来做。内存消耗也比较低:他们最大的动态器使用256MB。
做Elixir的Vault团队只有三个工程师。他们的大部分应用程序都是在内部使用的,所以他们一般不担心性能问题。他们继续使用Elixir,因为他们对它感到富有成效和满意。他们还发现,与以前的经验相比,这是一种更容易维护的语言。
关于Phoenix
这两个团队一般都使用Phoenix来开发网络应用,除非他们有理由不这样做,但这是很少的。他们承认,使用Phoenix不会有性能上的损失,而且你会得到很多东西。Phoenix使他们很容易选择加入他们需要的部分,并删除他们不需要的部分。
他们还发现更容易理解Phoenix本身在引擎盖下是如何工作的,特别是与他们以前使用其他框架(如Ruby on Rails)的经验相比。随着时间的推移,这些知识正不断帮助他们维护和更新他们的应用程序。
学习Elixir和壮大团队
两个Elixir团队的成长大多是有机的。鉴于他们的堆栈中有多种语言,他们经常特别为一种或另一种语言招聘,而不是专门为Elixir招聘。如果新的团队成员倾向于Elixir,他们会被进一步鼓励去探索和学习这种语言。他们也是结对编程的积极实践者,所以在他们的团队中有很多机会可以互相学习,轮流结对,交换项目,等等。
根据Matthew Peck的说法,"从面向对象的语言到函数式编程的范式转变是我们第一次学习Elixir时的最大挑战"。然而,该团队同意这种投资是值得的。"学习Elixir使我们成为更好的程序员。我们发现,不变性使我们的代码更易读,更容易测试,更简单地实现并发。现在当我们回到面向对象的语言时,我们正在考虑如何在那里应用同样的概念"--Mike Hagerdon说。
Amanda Dolan对Elixir编写并发和容错应用程序的能力发表了一些看法。"学习Elixir的另一个挑战是完全掌握并发性和Erlang/OTP模式"。他们中的一些人认为,掌握这些概念的时间比他们最初预期的要长。
Taylor Mock对团队采用Elixir时可能面临的挑战有自己的看法。"Elixir和我们以前的堆栈,Ruby和Node.js之间的另一个区别是在生态系统方面"。他们最初担心Elixir生态系统在第三方工具方面会有所欠缺,但他们看到的并非如此。Taylor继续说。"我们发现,利用语言本身提供的概念和机制,我们可以走得很远。这种转变可能是可怕的,但我们现在已经过去了,我们发现自己的应用程序更精简,依赖性更少"。
总的来说,两个团队都认为语言本身是很容易接近的。鉴于他们从一个小的概念验证开始,他们能够在前进的过程中解决他们在采用、开发和部署方面的问题。从历史上看,Heroku在Erlang方面也取得了很大的成功,这也促成了Heroku内部采用Elixir的成功。