【问题标题】:How does an Erlang gen_server start_link a gen_server on another node?Erlang gen_server 如何 start_link 另一个节点上的 gen_server?
【发布时间】:2012-09-05 19:00:05
【问题描述】:

我有一个 Erlang 应用程序,它有点太消耗资源而无法留在一个节点上。我正在让 gen_servers 从一个进程移动到另一个进程——结果证明这相对容易。我遇到了最后一个障碍:让创建这些 gen_servers 的工厂进程在远程节点而不是本地节点上生成它们。 start_link 的默认行为显然是仅在本地启动,但我没有看到任何改变它的选项。

看来我必须对解决方案有创造性,并想看看那里是否有人已经成功实施了类似的东西。 IOW,推荐的解决方案是什么?

编辑

我正在查看调用触发的调用链:

gen_server:start_link(?Module, Args, [])

gen_server:start_link/3:

start_link(Mod, Args, Options) ->
    gen:start(?MODULE, link, Mod, Args, Options).

gen:start/5:

start(GenMod, LinkP, Mod, Args, Options) ->
    do_spawn(GenMod, LinkP, Mod, Args, Options).

gen:do_spawn/5:

do_spawn(GenMod, link, Mod, Args, Options) ->
    Time = timeout(Options),
    proc_lib:start_link(?MODULE, init_it,
                        [GenMod, self(), self(), Mod, Args, Options], 
                        Time,
                        spawn_opts(Options));

proc_lib:start_link/5:

start_link(M,F,A,Timeout,SpawnOpts) when is_atom(M), is_atom(F), is_list(A) ->
    Pid = ?MODULE:spawn_opt(M, F, A, ensure_link(SpawnOpts)),
    sync_wait(Pid, Timeout).

这最终让我们找到了有趣的地方。有一个 spawn_opt/4 匹配:

spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
    ...
    ...

但是,有一个实际上对我有用:

spawn_opt(Node, M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
    ...
    ...

令我惊讶的是,这并没有暴露出来。我意识到粗心的程序员可能会尝试 gen_server:start_link 恰好在火星上运行的 erlang 节点上的进程,从而阻塞调用半小时,但可以肯定的是,这是程序员的注意。我真的坚持修改 OTP 或编写某种临时解决方案吗?

【问题讨论】:

    标签: erlang nodes distributed erlang-otp gen-server


    【解决方案1】:

    我们不直接start_link 远程节点上的服务器。为了良好的程序结构和简单性,我们在远程节点上启动一个单独的应用程序,并将远程进程的创建委托给远程应用程序中运行的某个进程。

    由于链接到进程主要是为了监督或监控,我们更喜欢与本地监督者而不是远程进程进行链接。如果你需要任何远程进程的存活状态,我推荐erlang:monitorerlang:demonitor

    典型的分布式设置:

    Node1
    +---------------+                          Node2
    | App1          |                          +---------------+
    |   Supervisor1 |  Proc Creation Request   | App2          |
    |     Processes | -----------------------> |   Supervisor2 |
    |     ......    |                          |      |
    |     ......    |                          |      | Create Children
    |     ......    |       Monitor            |      V
    |     ......    | -----------------------> |     Processes |
    +---------------+                          |     ......    |
                                               +---------------+
    

    【讨论】:

      【解决方案2】:

      也许rpc 模块可以帮助你。尤其是函数async_call

      【讨论】:

        猜你喜欢
        • 2011-08-09
        • 2014-11-09
        • 2011-10-08
        • 2016-08-09
        • 2019-07-17
        • 2014-05-12
        • 1970-01-01
        • 2016-10-19
        • 1970-01-01
        相关资源
        最近更新 更多