何塞·瓦利姆长生不老药的例子对我不起作用



我是elixir和分布式编程的新手。我在Youtube中尝试了Jose Valim从其他节点生成方法的示例。但它不起作用,也找不到正确的答案。

iex(bob@local)2> Node.spawn(:"alice@alice.local", fn -> Hello.world() end)
#PID<0.116.0>
22:05:12.657 [warn]  ** Can not start :erlang::apply,[#Function<20.128620087/0 in :erl_eval.expr/5>, []] on :"alice@alice.local" **

我尝试了这个分布式长生不老药示例中的所有建议;不起作用。帕努托说这都是关于IP的。我也尝试了Node.connect的东西。但我还是解决不了。我错过了什么?

有两种情况:

  • 要连接在同一台计算机上运行的两个Elixir节点,请打开两个终端窗口并尝试以下操作:

    1. 在终端窗口#1:

      $ iex --sname alice
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(alice@eugene-mbp)1>
      
    2. 在终端窗口#2中:

      $ iex --sname bob
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(bob@eugene-mbp)1>
      

    这里eugene-mbp是我的计算机的主机名,没有域部分。对于域部分,它看起来像这个eugene-mbp.local

  • 如果您想在两台独立的计算机上运行节点,但您只有一台计算机,您可能需要尝试Docker。打开两个终端窗口并尝试以下操作:

    1. 在终端窗口#1:

      $ docker run -it --rm --name node1 --hostname node1 --network example elixir:1.7-alpine iex --sname alice --cookie secret
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(alice@node1)1>
      
    2. 在终端窗口#2中:

      $ docker run -it --rm --name node2 --hostname node2 --network example elixir:1.7-alpine iex --sname bob --cookie secret
      Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]
      Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
      iex(bob@node2)1>
      

现在让我们回到从一个节点到另一个节点生成进程的问题上来。以下步骤将基于上面在同一台计算机上运行的示例

在终端窗口#1中运行以下命令:

iex(alice@eugene-mbp)1> Node.list()
[]
iex(alice@eugene-mbp)2> Node.ping(:"bob@eugene-mbp")
:pong
iex(alice@eugene-mbp)3> Node.list()
[:"bob@eugene-mbp"]

在上面的命令序列中,我们首先查看节点是否相互了解,而事实上它们并不了解。然后我们ping一个"bob"节点。然后我们再次检查节点是否相互认识,现在他们认识了!

现在,让我们在"bob"节点上定义一个模块。打开终端#2,并写下:

iex(bob@eugene-mbp)1> defmodule Hello do
...(bob@eugene-mbp)1> def world do
...(bob@eugene-mbp)1> IO.puts "Hello, world!"
...(bob@eugene-mbp)1> end
...(bob@eugene-mbp)1> end
{:module, Hello,
<<70, 79, 82, 49, 0, 0, 4, 40, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 140,
0, 0, 0, 15, 12, 69, 108, 105, 120, 105, 114, 46, 72, 101, 108, 108, 111, 8,
95, 95, 105, 110, 102, 111, 95, 95, 7, ...>>, {:world, 0}}

最后,让我们从"alice"节点中调用我们刚刚定义的这个函数。打开终端#1并运行它。下面是完整的输出:

iex(alice@eugene-mbp)4> Node.spawn(:"bob@eugene-mbp", fn -> Hello.world() end)
Hello, world!
#PID<10894.142.0>
iex(alice@eugene-mbp)5>

最新更新