两年后的Elixir和Phoenix

2021-04-06 04:05:30

两年后专业工作经过两年后的灵长素语言及其凤凰框架的思考。

我是一个经验丰富的网络开发商(主要用手用Ruby在Rails上工作)以及有机会在商业酏剂项目上工作的人。在过去的两年里,我写了很多酏剂,我必须从头开始学习。我一直发现这种个人帖子有趣,所以我想我会为你写一个。

如果您还没有听说过Elixir,我建议观看Elixir纪录片,以创建者JóseValim为一个开始。我不记得我是如何发现Elixir的方式,但最有可能来自一些Ruby社区新闻。我围绕着Elixir Space,阅读了很多令人兴奋的博客文章,并且一般印象深刻。什么让我兴奋于酏剂?虽然可以为elixir说许多好事,但我喜欢先发制人的调度程序和每个过程垃圾收集器的想法。为什么?

光束的预先发生(Erlang虚拟机)意味着系统在高负荷下表现合理。这不是一件小事。能够将遥控器连接到运行系统,并且尽管它在100%以下的情况下,它仍然在100%负载下是相当的。然后,每个流程GC意味着在处理Web请求时大部分时间都不会运行GC。两者都给你一个非常低的延迟。如果你想知道我在谈论什么,请通过sašajurić的erlang和elixir的灵魂观看优秀的视频。这是最佳视频,实现了什么光束是关于什么。

尽管我的兴趣,但我实际上从未去过任何Elixir。我甚至告诉自己,我很可能会通过酏剂。用红宝石/轨道的手似乎可以解决,并且迫使自己学习没有商业采用的语言是困难的。令我惊讶的是,一位精灵项目出现在布拉格无处不在,在那里我当时住在那里。

我正在全职工作,没有任何工作,我接受了:)。该项目本身并不公共,所以虽然我很乐意告诉你更多关于它的信息,但您仍然需要等待其公开发布会。

在表面上,Elixir感到红宝石,但很快你就会意识到它非常不同。这是一个强大的动态但编译的语言。总的来说,它设计得很好,拥有现代标准图书馆。

IEX> 1#Integer Iex> 0x1f#Integer Iex> 1.0#float iex>真#boolean iex> :Atom#原子/符号IEX> " elixir" #字符串IEX> [1,2,3]#list iex> [{:原子,"价值" },{:原子," value2" }]#关键词列表IEX> {1,2,3}#tople iex> 〜D [2021-03-30] #sigil iex> 〜r / ^ regex $ /#sigil

如您所见,没有数组。只需链接列表和相当特殊的关键字列表。我们在Ruby中有符号(具有与键访问的字符串混合它们的相同问题)和使用批量返回错误的元组(:确定vs {:错误,:name})。我喜欢元组如何使标准化的返回错误流动(即使它没有以任何方式强制执行)。

IEX>地图=%{A:1,B:2}%{A:1,B:2} IEX>地图[:a] 1 iex> %{MAP |答:3}%{A:3,B:2}

结构与映射类似,因为它基本上是一个包装器在它们之上。

我们可以使用TypeSpecs添加键入的结构和函数定义,但它们有限。 Elixir编译器不会使用它们。仍然,他们帮助文档,他们的语法实际上很好:

defmodule stringhelpers do @type word():: string。 t()@spec long_word? (word()):: boolean()def long_word? (Word)当IS_Binary(Word)进行字符串时。长度(字)> 8结束

可以说,我们确实得到了匹配的最佳模式之一。您可以在模式中匹配所有时间。由于模式匹配,您也几乎不需要静态键入。 Ruby也在那里了,但永远不会真正匹配Elixir的有益的模式匹配体验,这是在开始的模式匹配周围设计的。您在方法定义中的模式匹配 - 在案例语句中接受的参数,模式匹配以及您的常规代码。

def添加(nil,nil),do:{:错误,:无法_be_nil} def添加(x,nil),do:{:错误,:无法_be_nil} def添加(nil,y),do:{:错误,:无法_be_nil def添加(x,y),do:x + y

def add(nil,nil),do:{:错误,:无法_be_nil} def添加(x,y)当is_integer(x)和is_integer(y)做x + y结束def添加(x,y),do:{ :错误,:has_to_be_integer}

您还可以用Defguard / 1制作自己的警卫,所以防护装置可以非常灵活。

Elixir不是一种面向对象的语言。我们实际上只编写模块和函数。这有助于了解代码。没有自我。只是用管道进出功能和组合物。不幸的是,没有早期回报可能有用。

标准图书馆是优秀的,记录好。它感觉现代,因为它是现代化的。如果您之前尝试过Elixir,则可能记住必须使用外部库进行基本的日历,但这是过去。它不会尝试实施一切,因为哲学是您也可以依赖Erlang标准库。该示例可能是与ETS(Erlang术语存储),RAND和ZIP模块一起使用的函数。

叫erlang没有表现惩罚,当我遇到一个erlang呼叫时,它甚至没有觉得奇怪。一体化的所有意味着清洁,设计精美,特别是与Ruby相比,这在标准库中保持了很多遗留CRUFT。

Exdoc可能是您在Elixir世界中看到的第一个令人印象深刻的事情。继续进行并浏览Elixir Docs。精美的设计和良好的搜索,版本切换,日夜模式。我喜欢它。至于代码文档本身,Elixir很棒。主图书馆和模块(凤凰,苦艾酒)的文档也是如此。有些不太常见的人可以使用帮助。

Elixir的工具是那里最好的工具之一。静态类型检查或编辑器支持,即。您可以将您用作单个接口的组合,以满足您可能想要在给定项目周围执行的所有任务。从启动和编译项目,管理依赖项,运行自定义任务(比如Ruby的Rake)到发布部署。还有一种标准化的混合格式来格式化代码:

$ mix new mix_project&& CD mix_project $ mix deps.get $ mix deps.compile $ mix test $ mix格式$ mix发行版

有点恼人的是Erlang的构建工具螺纹道3,您将间接使用,并导致奇怪的编译错误:

==> myapp **(mix)无法编译依赖性:遥测," /home/strzibny/mix/rebar3裸致编译 - patanss =" / home / strzibny / projects / digi / backend / _build / dev / lib / * / ebin""命令失败。您可以重新编译" mix deps.compile etemetry",用&#34更新它; mix deps.update遥测"或用#34清洁它;混合DEPS.CLEAN遥测"

从混合开始,您将使用我已经详细编写的非常漂亮的IEX shell。关于IEX的我最喜欢的事情是项目的轻松重新编译:

唯一的烦恼来自于Elixir数据类型以及它们的工作方式。检查列表需要如下:

还有更多!光束还为您提供调试器和观察者。要启动调试器:

调试器的功能很清楚,观察员有助于监督流程和监督树,因为Erlang VM基于带有轻量级监督程序的演员模式。来自Ruby,我也喜欢编译器如何在访问程序之前捕获一堆错误。然后我们有透析器,可以捕获一大吨的东西,这是错误的,包括典型值的可选类型。但它远非完美(在功能和速度中),很多人都没有搭配它。

大多数开发人员都会寻求一个伟大的IDE或编辑集成。我使用升华文本与elixir语言服务器,我以前记录了设置。 Intellij Idea也有一个很好的插件,可能是您现在可以获得最好的。 Elixir不是Java,但很多好的事情就是工作。

对我来说唯一的真正麻烦是我的设置是非常饥饿的。因此,虽然超级有帮助,但我倾向于有时禁用它。一般来说,我会说编辑支持是以某种方式与Ruby相提并论,但我也相信Elixir的设计允许伟大的工具,我们尚未拥有它们。

测试Elixir代码非常好。我喜欢每个人都使用exunit。一件很酷的事情是医生:

#测试defmodule currencyconverstest do @moduledoc false使用exunit。案例,异步:真正的医疗currencyConversion ......结束#模块DefModule CurrencyConversion ... @doc""从货币A转换为B. ###示例IEX>转换(金钱.NEW(7_00,:CHF),:USD)%金额{金额:7_03,货币::USD}""" ... 结尾

上述文档示例将作为测试套件的一部分运行。甜的!

习惯于来自rails的东西是嘲笑的。虽然您可能喜欢最终结果,但它肯定更繁琐。这是因为你不能只覆盖红宝石世界中的任何东西。当我使用MOX库时,我通常必须:

为我的真实模块和我的新存根使用此行为(这将返回一个快乐的路径)

这样,您可以轻松测试默认响应,也可以使用MOX返回每个测试(例如错误响应)的其他东西。我有一个解释的帖子。

模块和功能的语言性质可确保您的测试很简单,而且多核支持可确保您的测试真的非常快。快速测试套件的缺点是您必须先编译它。因此,不一定期望在CI中的项目进行快速测试。但是,您将看到一旦它们变大,可以看到Rails测试套件的相当大。

Phoenix是Elixir的Go-web框架。它既不是范围的轨道,但既不是SINATRA这样的微型ramework。它有一些惯例,但你可以在没有任何大问题的情况下改变它们。部分原因是它基本上是一个图书馆,也是你用ecto,你的“orm”配对它。您将Elixir应用程序写作“与”凤凰,而不是撰写凤凰申请(如rails)。

除了快速(Elixir不是快速的Perse,而是模板例如是超效率,它有两个独特的功能,使其更加突出。

其中一个是LiveView,它允许您在不编写JavaScript的情况下构建交互式应用程序。第二个是Liveashboard,一个美丽的仪表板,内置于LiveView之上,您可以在2分钟内包含在您的应用程序中。它为您提供了许多有关当前运行系统的有用信息的标签(并且您也可以轻松切换节点)。其中一些是:

我希望Phoenix有一个像轨道这样的维护政策,所以它可以更认真地拍照。另一方面,我认为它不会更改。 Phoenix名称和徽标也是一个很好的触摸,作为对梁的容错公差的参考(您的Elixir进程将从灰烬中回来)。

在Web框架中对我很重要的是生产力。我不在乎我可以在c中制作最好的执行应用程序,或者有一切编译器检查。我关心完成的东西。我更喜欢为小型团队设计的框架,因为我希望自己富有成效。凤凰不是作为rails包含的电池,尽管具有Liveveashboard等功能可能比烘焙的动作文本更好。LiveView中有文件上传,但它不是一个完整的框架,如活动存储。所以它在生产力的轨迹后面,但它仍然是一个非常富有成效的框架。

我也很顺利,不仅适用于硬件,还可以更好地适用于码级。我喜欢从开始和引入上下文中拆分lib / app和lib / app_web的想法。上下文告诉您以一种以服务为导向的方式拆分您的LIB /应用程序,您可以将App / Consucting.ex或App / Account.ex作为您的应用程序的输入点。

另一个有趣的方面是,自编译菲尼克斯以来,浏览应用程序的开发版本不像Rails中的速度。它飞了。错误也非常好(并且每天都有错误报告和编译器警告都需要改进):

尝试插入结构时的约束错误:* unique_validation_api_request_on_login_id_year_week(unique_constraint)如果要停止违反此约束违反anexception,而是将其添加到Changeset上的错误,请使用约束:名称`作为选项。Changeset定义了以下约束:* unique_address_api_request_on_login_id_year_week(unique_constraint)

但我真的很喜欢的是什么? Phoenix全堆叠应用程序的开发。在资产管道和WebPacker(两个竞争解决方案)之间没有拆分,并且一切都在没有单独运行开发的WebPack服务器。您更改React组件,切换到Firefox窗口,更改在那里!你正在运行的唯一方法是你的mix phx.server。

但没有良好的图书馆,生产力就不会发生。虽然Elixir和Phoenix Eco-System具有一些出色的选择GraphQL(嗯)和条纹(条纹条纹),但云库和其他集成没有许多好的选择。我觉得条纹是这里唯一的例外,但这不是官方的SDK。

有时,如果您需要同时携带SOAP的运输功能,您的SOAP库也没有很有趣。但有时,这可能导致构建易于维护的最小解决方案。我们实际上有两个小模块,用于在Azure中使用对象存储。我之前博彩了关于我如何实现Azure预签名,如果您有兴趣。

Phoenix的部署可以简单地复制我已经提到的Mix释放到远程服务器。然后,您可以将其作为SystemD服务启动。虽然部署Elixir Web应用程序并不总是很简单,但它最近被嘲笑。想象一下,这样的东西:

$ mix deps.get - gix $ mix_env = prod mix compile $ npm install --prefix ./assets $ npm运行部署--prefix ./assets $ mix_env = prod mix mix phx.digest $ mix_env = prod mix发行new_phoenix $ Port = 4000 Build / Prod / Rel / New_Phoenix / Bin / New_Phoenix Start

当然,你也可以制作一个轻微的方式码头容器,但也许你甚至不需要。混合释放完全是独立的(甚至比Java的罐更好)!以下是如何用一点点上下文制作它们。唯一要注意的是他们是平台依赖的,所以你现在不能轻易编译它们。

虽然人们被授予Elixir的分布式性质,但它的性能也使其成为运行强大的单服务器的一个很好的平台(这是X-Plane Flight Simulator的Devs如何运行他们的Elixir后端)。特别是因为Elixir也支持热门部署,这是一种很酷的。但是,MIX版本不支持此选项。

Elixir(和Phoenix)社区很棒。我总是在Elixir论坛和其他地方得到快速而非常有帮助的答案。 Elixir是利基。但它不是水晶或nim niche。尽管如此,你不是一个例外,你直接从josévalim得到答案。他甚至可以回复这么快,仍然超出我:)。谢谢,jóse!

领奖台,素描,漂白板报告,Brex,Heroku和百事可乐是使用Elixir的着名品牌。 Elixir公司是一个追踪公共Elixir采用的网站。我是我自己在尚未公开的项目上,所以我相信他们更加灵活了!

如果您是关于Elixir的博客,请加入我们的Beambloggers.com。还有Elixirstatus为社区新闻。

这就是它。如果你感到惊讶,我没有进入OTP,这是因为我没有做太多的OTP。这确实很棒(你只是通过使用Phoenix获得的好处),但你可以使用Elixir而不做出很多OTP自己。

Elixir的某些专业人士是一种小型语言,您将学习快速,现代,精美记录的标准库,强大的模式匹配和理解功能,无头疼。我不喜欢的是,映射中的字符串VS atom键(没有rails hashwithindifferentaccess),我必须承认 - 有时我想念我的实例变量。

学习Elixir和Phoenix无疑值得。我认为它在技术上是建立我们今天的雄心勃勃的Web应用程序和软实时系统的最佳选择。它仍然缺少几个地区,但未来没有任何无法修复。如果不是Elixir,那么对于梁平台(见焦糖)。

我也喜欢那个elixir不仅仅是网络的语言。 IOT有神经,最近我们得到了Libtorch后端的NX。

我正在编写关于Web应用程序部署的完整指南。 Ruby用Puma,Python与枪手,Nginx,PostgreSQL,Redis,网络,流程,系统,备份和所有通常的嫌疑人。