Erlang:分布式应用程序奇怪的行为

Posted

技术标签:

【中文标题】Erlang:分布式应用程序奇怪的行为【英文标题】:Erlang: Distributed Application Strange behaviour 【发布时间】:2011-09-18 04:11:00 【问题描述】:

我使用分布式 erlang 应用程序付费。

配置和想法取自: http://www.erlang.org/doc/pdf/otp-system-documentation.pdf 9.9。分布式应用程序

我们有 3 个节点:n1@a2-X201、n2@a2-X201、n3@a2-X201 我们有应用程序 wd 可以做一些有用的工作:)

配置文件:

wd1.config - 对于第一个节点: [核心, [分布式,[wd,5000,['n1@a2-X201','n2@a2-X201','n3@a2-X201']], sync_nodes_mandatory,['n2@a2-X201','n3@a2-X201'], sync_nodes_timeout,5000 ] ,sasl, [ %% 所有报告都到这个文件 sasl_error_logger,file,"/tmp/wd_n1.log" ] ]。 第二个的wd2.config: [核心, [分布式,[wd,5000,['n1@a2-X201','n2@a2-X201','n3@a2-X201']], sync_nodes_mandatory,['n1@a2-X201','n3@a2-X201'], sync_nodes_timeout,5000 ] ,sasl, [ %% 所有报告都到这个文件 sasl_error_logger,file,"/tmp/wd_n2.log" ] ]。 对于节点 n3 看起来很相似。

现在在 3 个单独的终端中启动 erlang:

erl -sname n1@a2-X201 -config wd1 -pa $WD_EBIN_PATH -boot start_sasl erl -sname n2@a2-X201 -config wd2 -pa $WD_EBIN_PATH -boot start_sasl erl -sname n3@a2-X201 -config wd3 -pa $WD_EBIN_PATH -boot start_sasl

在每个 erlang 节点上启动应用程序: * 应用程序:开始(wd)。

(n1@a2-X201)1> 应用程序:开始(wd)。 =信息报告==== 2011 年 6 月 19 日::15:42:51 === wd_plug_server 开始... PluginId: 4 路径: "/home/a2/src/erl/data/SIG" FileMask: "(?i)(.*)\\.SIG$" 好的 (n2@a2-X201)1> 应用程序:开始(wd)。 好的 (n2@a2-X201)2> (n3@a2-X201)1> 应用程序:开始(wd)。 好的 (n3@a2-X201)2>

目前一切正常。正如 Erlang 文档中所写:应用程序正在节点 n1@a2-X201

上运行

现在杀死节点n1: 应用程序已迁移到 n2

(n2@a2-X201)2> =信息报告==== 2011 年 6 月 19 日::15:46:28 === wd_plug_server 开始... PluginId: 4 路径: "/home/a2/src/erl/data/SIG" FileMask: "(?i)(.*)\\.SIG$"

继续我们的游戏:杀死节点n2 再一次系统工作正常。我们在节点 n3

有我们的应用程序 (n3@a2-X201)2> =信息报告==== 2011 年 6 月 19 日::15:48:18 === wd_plug_server 开始... PluginId: 4 路径: "/home/a2/src/erl/data/SIG" FileMask: "(?i)(.*)\\.SIG$"

现在恢复节点 n1n2。 所以:

Erlang R14B (erts-5.8.1) [来源] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.1(使用 ^G 中止) (n1@a2-X201)1> Eshell V5.8.1(使用 ^G 中止) (n2@a2-X201)1>

节点 n1n2 又回来了。 看起来现在我必须手动重新启动应用程序: * 我们先在节点 n2 做:

(n2@a2-X201)1> 应用程序:开始(wd)。 看起来像是被吊死了…… 现在在 n1 重新启动它 (n1@a2-X201)1> 应用程序:开始(wd)。 =信息报告==== 2011 年 6 月 19 日::15:55:43 === wd_plug_server 开始... PluginId: 4 路径: "/home/a2/src/erl/data/SIG" FileMask: "(?i)(.*)\\.SIG$" 好的 (n1@a2-X201)2>

它有效。并且节点 n2 也返回了 OK:

Eshell V5.8.1(使用 ^G 中止) (n2@a2-X201)1> 应用程序:开始(wd)。 好的 (n2@a2-X201)2>

在节点 n3 我们看到:

=信息报告==== 2011 年 6 月 19 日::15:55:43 === 应用:wd 退出:停止 类型:临时

总的来说,一切看起来都不错,如文档中所述,除了在节点 n2 处启动应用程序的延迟。

现在再次杀死节点n1

(n1@a2-X201)2> 用户切换命令 --> q [a2@a2-X201 发布]$

操作……一切都挂了。应用程序未在其他节点重新启动。

实际上,当我写这篇文章时,我意识到有时一切都好,有时我有问题。

任何想法,虽然在恢复“主”节点并再次杀死它时可能会出现问题?

【问题讨论】:

好问题:很多票但没有答案:) 【参考方案1】:

作为explained over at Learn You Some Erlang(滚动到底部),分布式应用程序仅在作为发行版的一部分启动时才能正常运行,而不是在您使用application:start 手动启动它们时。

【讨论】:

【参考方案2】:

您看到的奇怪现象很可能与您完全在节点 n1/n2 上重新启动应用程序有关,而 n3 仍在初始应用程序初始化下运行。

如果您的应用程序启动任何系统范围的进程并使用它们的 pid,而不是使用设置为 global、pg 或 pg2 的注册名称,那么您可能正在使用两组全局状态。

如果是这种情况,建议采取的方法是专注于从现有应用程序中添加/删除节点,而不是重新启动整个应用程序。这样,节点就会离开并加入到现有的一组初始化值中。

【讨论】:

实际上,我不使用 PID,我使用注册名称。我使用 local,Name 注册了一些 gen_server 实现行为。所以,我觉得这应该不是问题。我不完全了解如何从正在运行的应用程序中添加/删除节点?你有任何代码示例吗?谢谢

以上是关于Erlang:分布式应用程序奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

Erlang 分布式 - 一些节点共享 1 个应用程序

Erlang NIF 奇怪的 iolist 行为

Erlang 通过 TLS 的分布式

您如何设计基于Erlang / OTP的分布式容错多核系统的架构?

erlang分布式编程

在 Erlang(和 Riak)中开发应用程序时的良好做法?