几乎每个成功的业务应用程序迟早都会进入需要水平扩展的阶段。 在许多情况下,您可以简单地启动一个新实例并降低平均负载。 但也有一些不那么简单的情况,我们需要确保不同的节点彼此了解并仔细分配工作负载。
结果很幸运 二郎,我们选择它是因为它令人愉快的语法和围绕它的炒作,它具有一流的
不同节点上的进程之间以及链路和监视器之间的消息传递是透明的[...]
在实践中,一切都有点复杂。 分散式 二郎 当“集装箱”指的是用于运输的大铁箱,而“码头工人”只是码头工人的同义词时,它就被开发出来了。 在 IP4 有许多未被占用的地址,网络中断通常是由老鼠咬断电缆造成的,生产系统的平均正常运行时间长达数十年。
现在我们都难以置信地自给自足、打包并运行分布式 二郎 在一个动态IP地址按照高度随机性原则分配的环境中,节点可以根据调度程序的突发奇想出现和消失。 为了避免在每个运行分布式的项目中出现大量样板代码 二郎,为了对抗敌对环境,需要帮助。
注意: 我知道有 libcluster
需求
我个人需要的是一个能够接管集群管理并具有以下属性的库:
- 使用硬编码节点列表和通过服务进行动态发现的透明工作 二郎;
- 每次拓扑更改的功能齐全的回调(那里的节点,这里的节点,网络不稳定,分裂);
- 用于启动具有长名称和短名称的集群的透明界面,如
:nonode@nohost
; - Docker 支持开箱即用,无需编写基础设施代码。
后者意味着我在本地测试应用程序后 :nonode@nohost
,或者在人工分布式环境中使用 test_cluster_task
docker-compose up --scale my_app=3
看看它如何在 docker 中执行三个实例而不需要更改任何代码。 我还想要依赖应用程序,例如 mnesia
- 当拓扑发生变化时,他们会在幕后实时重建集群,而无需应用程序进行任何额外的操作。
回廊 它的目的并不是成为一个具备从支持集群到制作咖啡等所有功能的图书馆。 它不是旨在涵盖所有可能情况的灵丹妙药,也不是理论家认为是学术上完整的解决方案。 CS 放入这个词中。 这个库的设计目的非常明确,但又完美地完成了它不太大的工作。 这个目标将是在本地开发环境和充满敌意容器的分布式弹性环境之间提供完全的透明性。
选择的方法
回廊 旨在作为应用程序运行,尽管高级用户可以通过直接运行来手动组装和维护集群 Cloister.Manager
在目标应用程序的主管树中。
当作为应用程序运行时,该库依赖于 config
,从中读取以下基本值:
config :cloister,
otp_app: :my_app,
sentry: :"cloister.local", # or ~w|n1@foo n2@bar|a
consensus: 3, # number of nodes to consider
# the cluster is up
listener: MyApp.Listener # listener to be called when
# the ring has changed
上述参数的字面意思如下: 回廊 用于 OTP 应用 :my_app
,用途 Erlang服务发现 连接节点,至少三个,并且 MyApp.Listener
模块(实现 @behaviour Cloister.Listener
通过此配置,应用程序 回廊 将 MyApp.Listener.on_state_change/2
%Cloister.Monitor{status: :up}
,这意味着:“您好,集群已组装完毕。”
大多数情况下,安装 consensus: 3
是最优的,因为即使我们期望有更多节点连接,回调也会通过 status: :rehashing
→ status: :up
在任何新添加或删除的节点上。
当以开发模式启动时,只需设置 consensus: 1
и 回廊 当他看到时,他会很高兴地跳过等待集群组装的过程 :nonode@nohost
或 :node@host
或 :[email protected]
- 取决于节点的配置方式(:none | :shortnames | :longnames
).
分布式应用管理
非真空的分布式应用程序通常包含分布式依赖项,例如 mnesia
。 我们可以很容易地从同一个回调中处理它们的重新配置 on_state_change/2
。 这里举例详细说明如何重新配置 mnesia
在飞行中
使用的主要优点 回廊 是它在拓扑更改后执行重建集群所需的所有操作 引擎盖下。 该应用程序只是在一个已经准备好的分布式环境中运行,所有节点都已连接,无论我们是否提前知道 IP 地址和节点名称,或者它们是否已被动态分配/更改。 这完全不需要特殊的 docker 配置设置,并且从应用程序开发人员的角度来看,在分布式环境中运行与在本地环境中运行没有区别。 :nonode@nohost
。 您可以阅读有关此内容的更多信息
尽管可以通过自定义实现来复杂地处理拓扑更改 MyApp.Listener
,可能总是存在边缘情况,其中这些库限制和配置偏差被证明是实现的基石。 没关系,照上面的就可以了 libcluster
,这是更通用的,甚至可以自己处理低级集群。 该代码库的目标不是覆盖所有可能的场景,而是使用最常见的场景,而不需要不必要的痛苦和繁琐的复制粘贴。
注: 在原文中,此时出现了“Happy clustering!”这一短语,而我用它进行翻译的 Yandex(我不必自己翻字典)为我提供了“Happy clustering!”选项。 也许无法想象更好的翻译,特别是考虑到当前的地缘政治局势。
来源: habr.com