Elixir/erlang 在哪里适合微服务方法?
Where does Elixir/erlang fit into the microservices approach?
最近我一直在用 docker compose 做一些实验,以便部署多个协作微服务。我可以看到微服务提供的许多好处,现在有一个很好的工具集来管理它们,我认为跳入微服务旅行车并不是很难。
但是,我也一直在试验 Elixir,我非常喜欢它本身提供的好处。鉴于它鼓励将您的代码打包到多个分离的应用程序中,并支持热代码升级,您将如何将 docker 与 elixir(或 erlang,就此而言)混合使用?
例如,如果我想使用 docker,因为它提供了 dev-prod 奇偶校验,那么 elixir 如何适应它?鉴于 docker 容器是不可变的,我失去了进行热代码升级的能力,对吧? blue/green 部署或金丝雀发布怎么样?
我的意思是,我可以用 Elixir 编写微服务并像使用任何其他语言编写一样使用它们,无论如何,多语言是微服务的好处之一,但我没有得到使用的全部好处OTP 平台,我想纯协作 erlang 应用程序比使用中间队列在用不同(或非)语言编写的微服务之间进行通信更优化。
这是一个非常开放的问题,但我将尝试说明为什么 Elixir/Erlang 可能是开发分布式系统的最佳平台(无论您是否使用微服务)。
首先,让我们从一些背景开始。 Erlang VM 及其标准库是为构建分布式系统而预先设计的,这一点确实得到了体现。据我所知,它是唯一在生产中广泛使用的时间和 VM,预先为此用例设计。
应用程序
例如,您已经暗示了"applications"。在 Erlang/Elixir 中,代码打包在以下应用程序中:
- 作为一个单元启动和停止。启动和停止系统就是启动其中的所有应用程序
- 提供统一的目录结构和配置API(不是XML!)。如果您已经使用并配置了 OTP 应用程序,那么您知道如何使用任何其他应用程序
- 包含您的应用程序监督树,以及所有进程(进程我的意思是 "VM processes" 是轻量级计算线程)及其状态
这种设计的影响是巨大的。这意味着 Elixir 开发人员在编写应用程序时有更明确的方法:
- 他们的代码是如何启动和停止的
- 构成应用程序一部分的进程是什么,因此应用程序状态是什么
- 如果发生崩溃或出现问题,这些进程将如何反应并受到影响
不仅如此,围绕这种抽象的工具也很棒。如果你安装了 Elixir,打开 "iex" 并输入::observer.start()
。除了显示有关实时系统的信息和图表外,您还可以终止随机进程,查看它们的内存使用情况、状态等。下面是在 Phoenix 应用程序中 运行ning 的示例:
此处的不同之处在于,应用程序和进程为您提供了一个抽象来推断生产中的代码。许多语言提供的包、对象和模块主要用于代码组织,而不反映 运行 时间系统。如果您有一个 class 属性或一个单例对象:您如何推断可以操纵它的实体?如果出现内存泄漏或瓶颈,如何找到负责的实体?
如果你问任何人 运行 一个分布式系统,这就是他们想要的那种洞察力,并且 Erlang/Elixir 你有它作为构建块。
通讯
这一切才刚刚开始。构建分布式系统时,需要选择通信协议和数据序列化器。很多人选择 HTTP 和 JSON,仔细想想,这对于执行真正的 RPC 调用来说是一个非常冗长和昂贵的组合。
使用 Erlang/Elixir,您已经拥有开箱即用的通信协议和序列化机制。如果你想让两台机器相互通信,你只需要给它们命名,确保它们有相同的秘密,你就完成了。
Jamie 在 2015 年的 Erlang Factory 上谈到了这个以及他们如何利用它来构建游戏平台: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
.
来引用它们
我可以更进一步,但我希望我已经在这一点上说服了你。 :)
最近我一直在用 docker compose 做一些实验,以便部署多个协作微服务。我可以看到微服务提供的许多好处,现在有一个很好的工具集来管理它们,我认为跳入微服务旅行车并不是很难。
但是,我也一直在试验 Elixir,我非常喜欢它本身提供的好处。鉴于它鼓励将您的代码打包到多个分离的应用程序中,并支持热代码升级,您将如何将 docker 与 elixir(或 erlang,就此而言)混合使用?
例如,如果我想使用 docker,因为它提供了 dev-prod 奇偶校验,那么 elixir 如何适应它?鉴于 docker 容器是不可变的,我失去了进行热代码升级的能力,对吧? blue/green 部署或金丝雀发布怎么样?
我的意思是,我可以用 Elixir 编写微服务并像使用任何其他语言编写一样使用它们,无论如何,多语言是微服务的好处之一,但我没有得到使用的全部好处OTP 平台,我想纯协作 erlang 应用程序比使用中间队列在用不同(或非)语言编写的微服务之间进行通信更优化。
这是一个非常开放的问题,但我将尝试说明为什么 Elixir/Erlang 可能是开发分布式系统的最佳平台(无论您是否使用微服务)。
首先,让我们从一些背景开始。 Erlang VM 及其标准库是为构建分布式系统而预先设计的,这一点确实得到了体现。据我所知,它是唯一在生产中广泛使用的时间和 VM,预先为此用例设计。
应用程序
例如,您已经暗示了"applications"。在 Erlang/Elixir 中,代码打包在以下应用程序中:
- 作为一个单元启动和停止。启动和停止系统就是启动其中的所有应用程序
- 提供统一的目录结构和配置API(不是XML!)。如果您已经使用并配置了 OTP 应用程序,那么您知道如何使用任何其他应用程序
- 包含您的应用程序监督树,以及所有进程(进程我的意思是 "VM processes" 是轻量级计算线程)及其状态
这种设计的影响是巨大的。这意味着 Elixir 开发人员在编写应用程序时有更明确的方法:
- 他们的代码是如何启动和停止的
- 构成应用程序一部分的进程是什么,因此应用程序状态是什么
- 如果发生崩溃或出现问题,这些进程将如何反应并受到影响
不仅如此,围绕这种抽象的工具也很棒。如果你安装了 Elixir,打开 "iex" 并输入::observer.start()
。除了显示有关实时系统的信息和图表外,您还可以终止随机进程,查看它们的内存使用情况、状态等。下面是在 Phoenix 应用程序中 运行ning 的示例:
此处的不同之处在于,应用程序和进程为您提供了一个抽象来推断生产中的代码。许多语言提供的包、对象和模块主要用于代码组织,而不反映 运行 时间系统。如果您有一个 class 属性或一个单例对象:您如何推断可以操纵它的实体?如果出现内存泄漏或瓶颈,如何找到负责的实体?
如果你问任何人 运行 一个分布式系统,这就是他们想要的那种洞察力,并且 Erlang/Elixir 你有它作为构建块。
通讯
这一切才刚刚开始。构建分布式系统时,需要选择通信协议和数据序列化器。很多人选择 HTTP 和 JSON,仔细想想,这对于执行真正的 RPC 调用来说是一个非常冗长和昂贵的组合。
使用 Erlang/Elixir,您已经拥有开箱即用的通信协议和序列化机制。如果你想让两台机器相互通信,你只需要给它们命名,确保它们有相同的秘密,你就完成了。
Jamie 在 2015 年的 Erlang Factory 上谈到了这个以及他们如何利用它来构建游戏平台: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
.
我可以更进一步,但我希望我已经在这一点上说服了你。 :)