Zen Erlang [和Elixir-大约 译者]

译者的介绍


本文是关于Erlang的 ,但是所说的一切都同样适用于ElixirElixir是在同一BEAM虚拟机上运行的一种功能语言。 它出现在2012年,现在正在积极发展。 Elixir获得了最熟悉的语法以及广泛的元编程功能,同时保留了Erlang的优点。


译者的更多内容

2016年的一篇文章,但它涉及的是不会过期的基本概念。


我(翻译)对概念和评论的引用位于方括号[] ,并标有“翻译说明”。


如果您发现翻译的某些部分不够正确,特别是在术语方面,或者遇到任何其他错误,请告诉我,我将很高兴对其进行更正。


特别感谢Jan Gravshin在校对和编辑文本方面的帮助。


这是我在Genetec组织的ConnectDev'16大会上的演讲的免费笔录(或较长的措辞?)。


001


我相信这里的大多数人从来没有用Erlang编程过。 您可能听说过,或者您知道名字。 因此,即使您从未遇到过这种语言,我的演讲也只会影响Erlang的高级概念,并且对您的工作或附带项目很有用。


002


如果您曾经对Erlang感兴趣,那么您会听说过座右铭“让它崩溃” [ “让它跌倒”-大约。 翻译者 ]。 我与他的第一次会面使我想知道到底是怎么回事。 Erlang本来应该适合多线程执行和容错,但是在这里他们建议我让一切都落空:与我真正想要的系统行为完全相反。 这个提议是令人惊讶的,但是,尽管如此,Erlang的Zen还是与之直接相关。


003


从某种意义上说,对Erlang使用“ Let it Crash”和“ Blow it up” [ Blow it !” -大约 火箭科学。 “炸毁”也许是火箭科学中最后想要的东西,而“挑战者”的灾难清楚地提醒了这一点。 另一方面,如果您以不同的方式看待情况,那么火箭及其整个推进系统将处理可能且将爆炸的危险燃料(这是一个危险的时刻),但是这种可控方式可以用来组织空间旅行或将有效载荷送入轨道。


而且这里的重点确实在控制之中。 您可以尝试将火箭科学视为正确控制爆炸的方法-至少可以控制爆炸的力量-用它们做自己想做的事。 反过来,您可以从相同的角度看待“让它崩溃”:这是关于容错的问题。 这个想法并不是在广泛的不受控制的故障中进行,而是将故障,异常和崩溃转变为可以使用的工具。


004


即将来临的秋天[即将来临的秋天-大约 转换器和受控退火是用火扑救的真实例子。 在我来自的萨格奈-拉克-圣让地区,定期对蓝莓田进行可控的焚烧,以帮助刺激和恢复其生长。 通常,您会看到森林不健康的区域被大火清除,以防止森林大火,因此在适当的监督和控制下会发生这种情况。 主要目标是清除可燃物,以免自然火进一步蔓延。


在所有这些情况下,大火席卷农作物或森林的破坏力被用来治愈农作物或防止森林大面积失控。


我认为“让它崩溃”的含义就是这样。 如果我们能够利用故障,崩溃和异常的优势,并使其成为一种可管理的方式,那么它们将不再是需要避免的可怕事件,而作为回报,它将成为组装大型可靠系统的强大构建元素。


005


因此,问题就变成了如何确保失败更具建设性而不是破坏性。 Erlang中用于此目的的主要芯片是过程。 Erlang进程是完全隔离的,并且具有不可分割的体系结构(不共享任何内容)。 任何进程都无法通过使所使用的数据失真来爬入他人的内存或影响其所做的工作。 这很好,因为这意味着具有100%保证的垂死进程将自行解决问题,并为您的系统提供了非常强大的故障隔离功能。


Erlang中的过程也非常轻巧,因此成千上万的过程可以同时工作而不会出现问题。 这个想法是根据需要使用尽可能多的过程,而不是尽可能多地使用。 想象一下,存在一种面向对象的编程语言,在该语言中,在任何给定的时间允许最多32个对象同时工作。 您很快就会得出结论,要在其上创建程序,这些限制太严格了,相当荒谬。 许多小过程的存在提供了更高的故障可变性。 在我们希望将失败的力量带给服务的世界中,这很好!


Erlang中进程的机制似乎有些奇怪。 当您使用C编写程序时,您将拥有一个大型main()函数,该函数可以完成大量工作。 这是程序的入口。 Erlang中没有这样的东西。 这些过程都不是主要过程。 每个进程都会启动一个函数,并且此函数扮演此特定进程的main()的角色。


现在,我们蜂拥而至,但是如果它们无法以任何方式进行交流,那么很难派遣它们来加强蜂巢。 蜜蜂跳舞[ 蜜蜂跳舞 -大约 译者 ],Erlang处理消息传递。


006


消息传递是竞争环境中最直观的通信形式。 从我们写信并由快递员将其发送给马的那一天开始,到更拿破仑发出的信号量( 光学信号量 -大约为),她是最需要处理的人之一 如图所示。 在后一种情况下,您只需将一伙家伙送到塔楼,给他们一个消息,然后他们挥舞旗帜,以比疲倦的马更快的速度在远距离传输数据。 逐渐地,这种方法被电报取代,电报又改变了电话和收音机,现在我们拥有了所有这些时尚的技术,可以非常远,非常快地发送消息。


所有这些消息传递的一个极其重要的方面(尤其是在过去)是,所有内容都是异步的,并且消息已被复制。 没有人整天站在门廊上等待快递员返回,也没有人(我怀疑)坐在信号灯旁,等待答案。 您发送了一条消息并返回了您的企业,随着时间的流逝,有人通知您答案已经到来。


这很好-如果另一侧没有响应,则直到死之前,您都不会卡在门廊上。 相反,如果您突然死了,接收者将不会面对这样一个事实,即最近到达的消息突然神奇地消失或改变。 发送消息时必须复制数据。 这两个原则确保了通信过程中的故障不会导致变形或无法修复的状态 翻译者 ]。 Erlang都实现了。


每个进程对于所有传入消息都有自己的邮箱。 任何人都可以写到进程邮箱,但是只有邮箱所有者可以查看它。 默认情况下,邮件按照接收顺序进行处理,但是某些功能(例如模式匹配[ 模式匹配 -大约。 转换器 ]可让您更改优先级,并持续或暂时关注任何一种消息。


007


你们中有些人会注意到我说的话很奇怪。 我继续重申,隔离性和独立性是如此美妙,以至于系统组件可以死掉而不会影响其余组件。 但是我也提到了许多流程或代理之间的通信。


每次在两个过程的对话开始时,它们之间就会隐含依赖性。 在连接两者的系统中出现隐式状态。 如果进程A向进程B发送消息,而B没有应答就死了,则A可以永远等待应答,或者在一段时间后拒绝通信。 第二种是可以接受的策略,但是它非常模棱两可:尚不清楚远程端是否已死亡或忙了这么长时间,并且没有上下文的邮件可以进入您的邮箱。


作为回报,Erlang为我们提供了两种解决此问题的机制:监视程序和链接[ 翻译者 ]。


监控者即将成为观察者。 您决定密切注意此过程,如果它由于某种原因而死了,则会有一条消息通知您收件箱中发生了什么。 您可以对此做出响应并根据找到的信息做出决定。 第二个过程永远不会知道您完成了所有这一切。 因此,如果您是观察员 ,则监视器非常好 译者 ]或照顾合作伙伴的身份。


链接[ 链接-大约 翻译者 ]-双向,并且创建者将两个相关过程的命运结合在一起。 当进程死亡时,与之关联的所有进程都会收到一条命令以终止[ 退出信号-大约0。 翻译者 ]。 反过来,这支队伍杀死了其他人[ 相关-大约。 翻译器 ]流程。


所有这些都变得非常有趣,因为您可以使用监视器来快速检测故障,并且可以将绑定用作体系结构设计,该体系结构允许您组合多个流程,从而将故障扩展到整个流程。 每当我的独立构建块彼此上瘾时,我就可以开始将其添加到程序中。 这很有用,因为它可以防止系统意外崩溃进入不稳定的,部分更改的状态。 连接可以确保开发人员:如果某件事发生了故障,那么它完全破裂了,留下了一张空白纸,并且丝毫不影响没有参加练习的组件。


对于此插图,我选择了用安全绳捆扎的登山者形象。 如果登山者仅相互连接,他们将发现自己处于悲惨境地。 每次有一个登山者滑行时,团队的其他成员将立即死亡。 这不是做生意的好方法。


相反,Erlang允许您指定某些进程是特殊的,并使用trap_exit参数标记它们。 然后,他们将能够接收通过通信发送的退出命令,并将其转换为消息。 这将使他们能够进行故障排除,并可能下载新程序来完成死者的工作。 与登山者不同,这种特殊的过程无法阻止伙伴关系过程的失败。 这已经是伙伴本身的责任,例如使用try ... catch构造实现。 捕获输出的过程仍然没有机会扮演另一个人的记忆并保存它,但是可以避免共同死亡。


这正在成为创建主管的关键机会。 我们将尽快与他们联系。


008


在转到主管之前,让我们看一下剩下的一些要素,这些要素将使我们能够成功地准备一个使用滴剂以造福自己的系统。 其中之一与流程调度程序的工作方式有关。 我要提及的真实案例是阿波罗11 登月[ 阿波罗11号 -大约 翻译者 ]。


阿波罗11号于1969年登上月球。 在图像中,我们看到了登月舱,上面装有Buzz Aldrin和Neil Armstrong,我相信这张照片是由迈克尔·科林斯(Michael Collins)拍摄的,他仍然在命令舱中。


在登上月球的途中,该模块由Apollo PGNCS(主要制导,导航和控制系统)[ Apollo PGNCS-大约。 翻译者 ]。 控制系统以经过仔细计算的周期数执行了多项任务[ CPU-大约0。 译者 ]。 NASA还发现处理器的使用量不得超过其容量的85%,而库存中应免费使用15%。


由于宇航员希望制定可靠的备用计划以防他们不得不中断任务,因此他们离开了会议的雷达,并启用了命令和服务模块-这将派上用场。 这样可以很好地加载剩余的CPU电源。 Buzz Aldrin一旦开始输入命令,就会开始出现有关过载的消息,实际上是关于超出可用计算能力的消息。 如果这个系统误入歧途,那么可能将无法完成其工作,一切都将以两名死去的宇航员结束。


首先,出现过载是因为雷达存在已知的硬件问题,从而导致其频率与控制计算机的频率不匹配,从而导致“盗窃”周期的次数比其他情况要多得多。 NASA的员工不是白痴,他们没有使用未经现实生活考验的新技术来完成如此重要的任务,而是重复使用了久经考验的组件,他们知道这些错误很少。 但是,更重要的是,他们提出了优先级计划。


这意味着,当该雷达或输入的命令给处理器增加过多的负载时,它们的任务就会被杀死,从而使CPU周期分配给优先级更高且确实需要它们的重要事物。 那是在1969年。如今,有更多的语言和框架提供协作调度,仅此而已。


Erlang不是应用于重要系统的语言,它仅考虑了实时的软约束-大约。 而不是严格的实时限制,因此在这种情况下使用它不是一个好主意。 但是,Erlang提供了主动计划[ 她是抢先式计划,大约。 译者 ]和流程优先级。 这意味着,作为开发人员或系统架构师,您不必担心为防止冻结,绝对每个人都应仔细计算其组件(包括使用的库)所需的CPU负载。 他们根本无法获得这种力量。 而且,如果您希望在需要时执行一些重要任务,也可以提供它。


这似乎不是一个严重或频繁的需求,并且人们仍然仅基于并行流程的协作调度来发布真正成功的项目,但是它无疑是非常有价值的,因为它可以保护您免受他人错误以及您自己的错误的影响。 它还为自动负载平衡,“惩罚不良”或“鼓励良好”流程或为具有更多任务的流程分配更高的优先级之类的机制打开了大门。 所有这些最终使您的系统足够适应负载和不可预见的事件。


009


作为确保体面的弹性的一部分,我想讨论的最后一个组件是在网络上工作的能力。 在任何考虑长期活动的系统中,必须能够在一台以上的计算机上快速运行。 您不想坐在金色轿车锁在钛金属车门后的某个地方,而无法补偿主要影响用户的故障。


迟早您将需要两台计算机,这样一来,如果您想在故障期间部署系统的一部分,则可以避免第二台计算机,甚至第三台计算机的故障。


图中的飞机-F-82双野马[ F-82双野马 -大约。 译者 ],这是一架在第二次世界大战期间设计的飞机,用于护送轰炸机,使其超出大多数其他战斗机无法覆盖的距离。 他有两个客舱,以便飞行员可以轮班控制该设备。 在适当的时候,可以划分职责,以便一名飞行员可以驾驶飞机,第二名可以控制雷达,起到拦截机的作用。 现代飞机仍然具有类似的能力; 他们拥有无数的重复系统,并且机组人员经常在飞行中入睡,因此,如果有必要,总是有人准备立即接管飞机的控制。


对于编程语言或开发环境,尽管很显然在开发服务器堆栈时,您将需要使用多个服务器,但是大多数设计时都不可能进行分布式工作。 但是,如果您要使用文件,则标准库中有一些用于此目的的工具。 大多数语言最多可以提供套接字支持或HTTP客户端。


Erlang向分布式系统的现实致敬,并为它们的创建提供了一个实现,该实现是有文档记录的,并且是透明的。 , , - [ pylyglot systems — . ].


010


" ". - , . "Let it crash" , , .


— .


011


[ supervision trees — . ] — , . — , — — , . , — "OTP", , "Erlang/OTP" [ OTP — Open Telecom Platform — . ].


— , , , , , "" . , : , , .


, , , , — .


012


. " , ". , . .


. " " [ one for one — . *]. . , .


— " " [ one for all — . *]. , . , , . , . , . , , . , , !


, , , . , . : , .


, . — " " [ rest for one — . ]. , , . .


[ , — — . ] . 1 , 150 .


013


, , " , !"


. , , , . "" [ — . ] "" [ — . ], Jim Gray 1985 ( Jim Gray, !)


-, — , , . . , , . , , , , .


— , , , . , , . , , .


, , .


014


, — .


, . , , .


, — , , . , — ; . , , . , , , .


, , .


. , , [ Property-Based Testing Basics , Property-based testing — . ] ( ), — - , . , , , .


015


( ). , , .


, . , , , , . - -.


. , , , , , , .


, . Jim Gray, , , 132 , , . 131 132 , , . , , , , ; , , , 100 000 , — 10 , - .


, , .


016


?


, . . , . , , . , "" Facebook ( ), , , Facebook .


, , , , . , , .


, . : , , , , .


, ( ), , . , .


017


, , . , , , .


, , .


018


() . , : . Tally () , Live Reports ( ) .


, . District (; ) , (Storage). (Cache) ( ) (Worker pool).


[ supervision strategies — . ], , , , . , " ", , , . ( ) " ". , (OCR) , , . , , , , .


OCR , C , . , C, , , .


, , , . 10 , , , .


, , . , . — , .


, , , . OCR C , . OCR . . , , ( ). , , — , .


OCR , . , , — . — . , , , , - , .


, . , — - , - ( ) , . , — , . — let it crash!


. , if/else , switch ', try/catch . , , , . [ , — . ], .


019


, , , , . : , .


, , , . (, SMS).


, , , , , .


020


OTP. OTP- — , . , , . , , , . , , , .


, OTP- . OTP-, . [: OTP-, , ]


:


  • , ;
  • , , , ;
  • , ;
  • , , , , ;
  • ( , );
  • .

. , . , , . , — , , .


021


, ? , . , Heroku .


. (vegur) , , , . , , .


- , . , : 500 000 1 000 000 ! , . ? , , , 100 000 , ? - 1:17000 1:7000. , , , .


, . , , , . , . , , .


022


. .


, - : " , . , , , . , , . , ."


. .


, , , 60 . ( United 734), , , , - . , , , , ABS, .


( ), . , . , , .


023


, . ( , ) Richard Cook. , YouTube, .


- . , , , .. — ( , , ..) , , - , .


, , , . , , - - .


, , , . , . , . - - , , , .


024


, . , , : , . . , , , .


, , , . .


025


, , . , , , .


. , , , - , , , , , . , .


026


, 'let it crash' — , , , , , — , , , . . fail-fast , , " ", .


, . , , . . , , . Let it crash.


027


: , , , — . , ( , !) .

Source: https://habr.com/ru/post/zh-CN443290/


All Articles