这是一个非常开放的问题,但我将尝试说明为什么 Elixir/Erlang 可能是开发分布式系统的最佳平台(无论您是否使用微服务)。
首先,让我们从一些背景开始。 Erlang VM 及其标准库是为构建分布式系统而预先设计的,这一点确实得到了体现。据我所知,它是唯一在生产中广泛使用的运行时和虚拟机,为此用例预先设计。
应用领域
例如,您已经暗示了“应用程序”。在 Erlang/Elixir 中,代码打包在应用程序内:
- 作为一个单元启动和停止。启动和停止系统就是启动其中的所有应用程序
- 提供统一的目录结构和配置API(不是XML!)。如果您已经使用并配置了开放电信平台 (OTP) https://en.wikipedia.org/wiki/Open_Telecom_Platform应用程序,您知道如何与任何其他应用程序一起工作
- 包含您的应用程序监督树,其中包含所有进程(我所说的进程是指“VM 进程”,它们是轻量级计算线程)及其状态
这个设计的影响是巨大的。这意味着 Elixir 开发人员在编写应用程序时可以采用更明确的方法来:
- 他们的代码是如何启动和停止的
- 构成应用程序一部分的进程是什么,因此应用程序状态是什么
- 如果发生崩溃或出现问题,这些进程将如何反应并受到影响
不仅如此,围绕这个抽象的工具也很棒。如果您安装了 Elixir,请打开“iex”并输入::observer.start()
。除了显示有关实时系统的信息和图表之外,您还可以杀死随机进程,查看它们的内存使用情况、状态等。以下是在 Phoenix 应用程序中运行此示例:
这里的区别在于应用程序和流程为您提供了抽象来推理生产中的代码。许多语言提供的包、对象和模块主要用于代码组织,而不反映运行时系统。如果您有一个类属性或一个单例对象:您如何推断可以操作它的实体?如果出现内存泄漏或瓶颈,如何找到对此负责的实体?
如果你问任何运行分布式系统的人,这就是他们想要的洞察力,而使用 Erlang/Elixir,你可以将其作为构建块。
沟通
所有这一切实际上只是一个开始。在构建分布式系统时,您需要选择通信协议和数据串行器。很多人选择 HTTP 和 JSON,仔细想想,这对于执行真正的 RPC 调用来说是一个非常冗长且昂贵的组合。
使用 Erlang/Elixir,您已经拥有开箱即用的通信协议和序列化机制。如果您想让两台机器相互通信,您只需给它们命名,确保它们具有相同的秘密,然后就完成了。
Jamie 在 2015 年 Erlang Factory 上谈到了这一点,以及他们如何利用这一点来构建游戏平台:https://www.youtube.com/watch?v=_i6n-eWiVn4 https://www.youtube.com/watch?v=_i6n-eWiVn4
如果您想使用 HTTP 和 JSON,那也很好,Plug 之类的库和 Phoenix 之类的框架也将保证您在这里也能高效工作。
微服务
到目前为止我还没有谈论微服务。这是因为,到目前为止,它们并不重要。您已经在围绕非常小的隔离进程设计系统和节点。如果您愿意,可以将它们称为纳米服务!
不仅如此,它们还被打包到应用程序中,将它们分组为可以作为单元启动和停止的实体。如果您有应用程序 A、B 和 C,然后您想将它们部署为 [A, B] + [C] 或 [A] + [B] + [C],那么这样做会遇到很少的麻烦,因为其固有的设计。或者,更好的是,如果您想避免预先将微服务部署的复杂性添加到系统中,您可以将它们全部部署在同一节点中。
而且,归根结底,如果您使用 Erlang 分布式协议运行所有这些,您可以在不同的节点中运行它们,并且只要您通过以下方式引用它们,它们就能够到达其他节点:{:node@network, :name}
代替:name
.
我可以更进一步,但我希望我已经说服了你。 :)