3.缺点处理
Elixir 的核心概念就像Joe Armstrong 所说的那样, 期望一个应用法度榜样可以一向运行。厩ㄑ用 Go 调用调剂器,你也可以经由过程 Go 的 suture 库实现一个监管法度榜样。
Elixir 实际上有很多配制揭捉?项,但首选的办法照样经由过程优良的distillery包。它将应用法度榜样封装成一个包含所依附(能在目标系同一并安排)二进制文件。
Elixir和Go都应用了调剂器来实现它们的并发模型,这两门说话生成支撑多核,但JavaScript不支撑。
缺点处理是这两门说话差别最大年夜的处所。大年夜函数调用到panics(Go 的崩溃异常), Go 对各个层次的缺点处理都很明白。Elixir的缺点处理被认为有种"代码的味道"。过会再来读一遍。
它是若何工作的呢?是否还记得先前我们谈论过Elixir的spawn调用会返回一个过程ID?它不仅仅是用来发送消息的,还可以用来监控过程并检查它是否还在晃荡状况。
因为过程的价值小,Elixir的标准做法是一次性创建两个,一个用来运行,一个用来监督。
这种办法被成为治理者模式。Elixir的应用往往在一种监管树内运行。 监管者过程经由过程一个叫spawn_link的函数创建过程, 如不雅被创建过程崩溃,那么创建过程也会崩溃。监管者进会处理这些崩溃,并敏捷重启过程。
一个例子,用被监管的过程做除法运算。被0除将过程崩溃掉落,但监管过程会急速将其重启,让将来的操作得以持续履行。不是缺点处理不存在,而是被监管过程处理掉落了。
如许做的目标是在可能出现异常的处所都要加上异常处理,不管是不是在goroutine 里。
Goroutine 可以用雷同的方法将缺点传递给管道。然而,如不雅 panic 出现,每个 goroutine 必须有应对之策,不然全部法度榜样都邑崩溃掉落。panic 不合于其他说话里的异常,它的目标是体系级别"停止任何工作"的事宜。
这种异常被封装在内存不足的缺点里。如不雅 goroutine 触发了一个内存不足的缺点,因为共享内存运行时的状况,即就是有对应的缺点处理也会导致法度榜样的崩溃。
对于 Elixir, 因为每个过程都有本身自力的堆空间,也就可以各自设置堆的最大年夜值,一旦跨越这个最大年夜值过程就会崩溃,然后会被零丁做垃圾收受吸结束重启,不会影响其他器械。
这并不是说Elixir 是无敌的。VM 依然可以经由过程其他方法耗尽内存, 但在过程中该问题是可控的。
并不是为了袭击 Go, 所有你据说过的应用共享内存的说话都要面对该问题。这只是Erlang / Elixir设计上的一个特点。
注: 你在大年夜多半办事器上用 Go 实现的处理法度榜样都已处理panic 缺点。是以,一次 Web 请求出现的崩溃,不足以干掉落一个过程。即便如斯,你依然要在 goroutine 上解决它。这个解释不是为了暗示 Go 的脆弱,毕竟它也不是 :)
4.可变与弗成变
在 Go 与 Elixir 的比较中,懂得可变类型与弗成变类型数据比较所产生的衡量是十分重要的。
Go 应用与大年夜多半法度榜样员所用过的雷同的内存治理风格,经由过程共享内存、指针和数据构造 对内存进行更改或从新分派。在处理大年夜的数据构造的时刻,这种方法效力更高。
Elixir的弗成变数据应用了写入时拷贝。在雷同的堆空间中,它实际上是传递一个指向数据的指针,但只要对其履行操作,就会创建一个新的副本。
5.集群
另一个出自可变与与弗成变比较的衡量是集群化。应用 Go, 可以无缝的履行长途调用。但因为指针和共享内存的存在,如不雅你在长途的终端调用一个引用了本地参数的办法,这就不会像预期那样履行了。
对于 Elixir,所有的器械都是经由过程消息传递的,所以全部应用法度榜样栈可以在随便率性数量的机械上集群化。数据被传入返回响应的函数中。任何函数函数调用都不会产生内存中的转换,这就许可Elixir像其他函数调用它本身的堆客栈一样,可以在不合的客栈、不合的机械、或完全不合的数据中间。
很多应用不须要集群化,但也有很多应用大年夜中受益,例如用户大年夜不合的机械连接的聊天法度榜样或程度分布的数据库都邑用到的通信体系。两者分别可以应用Phoenix 框架的管道和 Erlang 的 Mnesia数据库的解决筹划。集群对于任何应用法度榜样的横向扩大才能都是十分重要的,而不依附于有机能瓶颈的中心节点。
6.库
Go 拥有一个广泛标准库,许可大年夜多半开辟者在不须要第三库的情况多做任何事。
Go 的快速和针对性的解决筹划异常合适工程化。Elixir 创建一个情况,即使在安排的时刻,不合的法度榜样也可以共存,操作和交换,且互不干扰 。Go 可以用来构建单个微办事, 而一个 Elixir 的umbrella情况里可以构建多个微办事。
Elixir标准库更显得简洁一些,但也包含Erlang 的看维它的库更周全,还包含三个内置的数据库 ETS/DETS/Mnesia。其他的包,必须大年夜其他的三方库中提取。
Elixir 和 Go 都有大年夜量的第三方库可以用。Go 应用go get惹人长途的包。Elixir 应用 Mix, 一个构建对象,它会像用户所熟悉的其他说话的担保理方法调用Hex包。
Go仍在尽力实现一个完全的担保理筹划。三方库与标准库比拟,Go 社区的大年夜多半人在可能的情况下更偏向于应用标准库。今朝 已经有几个担保理对象可以用了。
7.安排
Go 的安排很简单。一个 Go 应用法度榜样被编程成一个包含所有依附的二进制文件,可以在本地运行,也可以夸平台。Go 的编译器可以针对任何架构的框架进行编译,而不管运行的计算机是什么样的。这是 Go 最大年夜的优势。
两者的差别在于, Elixir 的编译所用的架构必须与目标体系的架构雷同才行。这些文档(这里应当是 链接)包含了这个场景的几个解决办法,但最简单的办法是在具有目标架构的Docker容器中构建发行。
应用这两种解决筹划,都必须要停止正在运行的代码,调换二进制文件,然后按大年夜多半 blue-green 风格的安排方法重启应用。
推荐阅读
沙龙晃荡 | 3月31日 京东、微博、华为拭魅战专家与你合营商量容器技巧实践! 细心的市平易近不难发明,地铁部分进出站闸机已经新增了二维码辨认区域。日前,记者探访发明,除了此前已经试水扫>>>详细阅读
本文标题:Elixir与Go多角度对比:背景+编程风格+并发处理
地址:http://www.17bianji.com/lsqh/40936.html
1/2 1