Elixir:Supervisor、GenServer 和 Application 之间的区别

Hel*_*rld 8 elixir erlang-supervisor

我正在练习这个例子。
https://github.com/kwmiebach/how-to-elixir-supervisor

我按照说明进行操作并了解其工作原理,但我无法理解 Supervisor、GenServer 和 Application 之间究竟有何不同。

有人可以解释这 3 种有何不同以及何时应该使用它们吗?

小智 11

首先,这些都是“OTP 设计原则”(并由标准库支持),它们都是在基本 Erlang 原语(如进程)之上的包装器(或者更好的说法是抽象)。这意味着它们不是在 Erlang 中编程的唯一方式(因此是 Elixir),但它们由社区共享并得到数十年经过实战考验的现实世界系统的支持。所以你也应该使用它们。


GenServer通常被认为是使用 Elixir 实现的应用程序的基本运行时构建块。尽管实际上它是对较低级别的 Erlang Process 原语的封装,但是,GenServer它在标准接口中提供了许多高级功能,例如调试和跟踪。基本上,您通常会使用(许多)GenServer来管理应用程序中的状态和“执行实际工作”。


Supervisor,正如文档所暗示的那样

监督者是监督其他进程的进程,我们将其称为子进程。监督者用于构建称为监督树的分层流程结构。

因此,从某种意义上说,它“管理” GenServers,但也“管理”其他Supervisors(以及其他 Erlang Process 抽象,如果它们实现了适当的接口)。您通常不会放入任何自定义逻辑Supervisor模块中,部分原因是它们的角色非常专注——只需管理子进程的生命周期。但也要使其不易出错(由您的更改引入)。

换句话说,Supervisor它不会为您的应用程序做任何实际的“工作”,它只是用于“布局”系统的架构。


相较于他人,Application不是一定是“运行时间关注”,因为二郎神文档建议

...使代码成为一个应用程序,即一个可以作为一个单元启动和停止的组件,也可以在其他系统中重复使用

所以Application实际上是将东西捆绑到一个“单元”中,而实际系统通常由许多这样的单元组成 - 例如,每当您运行一些 Elixir 代码时,还有一个"elixir" Application运行多个进程,例如elixir_code_server

Elixir 运行时

更重要的是,Application是在 OTP 设计原则中共享(重用)代码的方式。当你定义一个应用程序时,它可以有一个“root supervisor”,它与应用程序一起启动。或者它也可以只有功能代码,根本不运行任何进程,如JSON 库。无论哪种方式,要跨不同系统重用代码,都需要将它们打包成Applications。


最后,我建议阅读一下:https : //ferd.ca/the-zen-of-erlang.html它解释了(至少对我而言)我们如何从基本(Erlang)流程到主管(和监督树),以及一些 OTP 应用程序。(以及我们应该如何在 BEAM 中进行编程)