Elixir / erlang在哪里适合微服务方法?

时间:2015-05-24 09:54:33

标签: architecture erlang docker elixir microservices

最近我一直在用docker compose做一些实验,以便部署多个协作微服务。我可以看到微服务提供的许多好处,现在有一个很好的工具集来管理它们,我认为跳进微服务车并不是很难。

但是,我也一直在尝试Elixir,我非常喜欢自己提供的好处。鉴于它鼓励将代码打包到多个解耦的应用程序中,并支持热代码升级,你如何将docker与elixir(或者erlang)混合使用?

例如,如果我想使用docker因为它提供了dev-prod奇偶校验,那么elixir如何适应呢?鉴于docker容器是不可变的,我失去了进行热代码升级的能力,对吗?蓝色/绿色部署或金丝雀发布怎么样?

我的意思是,我可以用Elixir编写微服务并使用它们就像用任何其他语言编写一样,多语言无论如何都是微服务的好处之一,但后来我没有得到使用OTP的全部好处平台,我想纯粹的协作erlang应用程序比使用中间队列在用不同(或非)语言编写的微服务之间进行通信更加优化。

1 个答案:

答案 0 :(得分:128)

这是一个非常开放的问题,但我将尝试说明为什么Elixir / Erlang可能是开发分布式系统的最佳平台(无论您是否使用微服务)。

首先,让我们从一些背景开始。 Erlang VM及其标准库是为构建分布式系统而设计的,这确实显示出来了。据我所知,它是在此用例中预先为生产设计的唯一运行时和VM。

应用

例如,您已经暗示过“应用程序”。在Erlang / Elixir中,代码打包在以下应用程序中:

  1. 作为单位启动和停止。启动和停止系统是启动其中所有应用程序的问题
  2. 提供统一的目录结构和配置API(不是XML!)。如果您已经使用并配置了OTP应用程序,那么您就知道如何使用任何其他应用程序
  3. 包含您的应用程序监督树,包含所有进程(通过进程我的意思是“VM进程”,它们是轻量级的计算线程)及其状态
  4. 这种设计的影响是巨大的。这意味着Elixir开发人员在编写应用程序时有更明确的方法:

    1. 他们的代码如何启动和停止
    2. 构成应用程序一部分的进程是什么,因此应用程序状态是什么
    3. 如果发生崩溃或出现问题,这些过程将如何反应并受到影响
    4. 不仅如此,围绕这种抽象的工具也很棒。如果您安装了Elixir,请打开“iex”并输入::observer.start()。除了显示有关您的实时系统的信息和图表,您还可以杀死随机进程,查看其内存使用情况,状态等。以下是在Phoenix应用程序中运行它的示例:

      Observer running with a Phoenix application

      这里的不同之处在于,应用程序和流程为您提供抽象来推断您的代码在生产中。许多语言主要为代码组织提供包,对象和模块,而不反映运行时系统。如果你有一个类属性或一个单例对象:你如何推理可以操作它的实体?如果您有内存泄漏或瓶颈,您如何找到负责它的实体?

      如果你问任何一个运行分布式系统的人,那就是他们想要的那种洞察力,而对于Erlang / Elixir,你将它作为构建块。

      通信

      所有这一切都只是开始。构建分布式系统时,需要选择通信协议和数据序列化程序。很多人选择HTTP和JSON,当你考虑它时,它是一个非常冗长和昂贵的组合,用于执行真正的RPC调用。

      使用Erlang / Elixir,您已经拥有了开箱即用的通信协议和序列化机制。如果你想让两台机器相互通信,你只需要给它们起名字,确保它们有相同的秘密,你就完成了。

      Jamie在Erlang Factory 2015上讨论了这个问题以及他们如何利用它来构建游戏平台:https://www.youtube.com/watch?v=_i6n-eWiVn4

      如果你想使用HTTP和JSON,那也很好,像Phoenix这样的插件和框架这样的库也可以保证你在这里也很有效率。

      微服务

      到目前为止,我还没有谈到微服务。那是因为,到目前为止,它们并不重要。您已经在围绕非常小的孤立进程设计系统和节点。如果你愿意,可以称他们为nanoservices!

      不仅如此,它们还被打包到应用程序中,这些应用程序将它们组合为可以作为单元启动和停止的实体。如果您有应用程序A,B和C,然后您想将它们部署为[A,B] + [C]或[A] + [B] + [C],那么这样做会很困难他们固有的设计。或者,更好的是,如果您想避免将微服务部署的复杂性预先添加到系统中,您可以将它们完全部署在同一节点中。

      而且,在一天结束时,如果您使用Erlang分布式协议运行所有这些,您可以在不同的节点中运行它们,只要您通过{{{{{{{{{ 1}}而不是{:node@network, :name}

      我可以走得更远,但我希望我已经说服了你。 :)