尝试从脚本 RPC 到另一个节点,使用“短名称”时一切正常,但使用“长名称”时失败。
我的本地机器名称是“Pandora”,启动分离节点后,
erl -detached -noshell -name 'node1@Pandora' -setcookie pandemic
使用
name_domain => shortnames
, 运行此脚本
#!/usr/bin/env escript
-mode(compile).
-define(THIS_NODE, 'testnode@Pandora').
-define(THAT_NODE, 'node1@Pandora').
show(R) -> io:format("~p~n", [R]).
main(_) ->
net_kernel:start(?THIS_NODE, #{name_domain => shortnames}),
erlang:set_cookie(?THAT_NODE, pandemic),
show( erl_epmd:names() ),
show( net_adm:names() ),
show( net_adm:ping(?THAT_NODE) ),
show( rpc:call(?THAT_NODE, erlang, time, []) ).
工作正常并产生以下结果:
{ok,[{"node1",40965},{"testnode",35319}]}
{ok,[{"node1",40965},{"testnode",35319}]}
pong
{14,1,21}
但是,当我将其更改为
name_domain => longnames
,以模拟在分布式环境中工作时):
net_kernel:start(?THIS_NODE, #{name_domain => longnames}),
测试失败并出现错误报告:
=ERROR REPORT==== 6-Oct-2024::14:09:07.875238 ===
** System running to use fully qualified hostnames **
** Hostname Pandora is illegal **
显然,“Pandora”不是 FQDN,因此我尝试通过创建一个名为 erl_inetrc
的本地Inets Configuration 文件并将本地域设置为我的办公室路由器的域来解决此问题:
{domain, "myoffice.loc"}.
在我的测试脚本中也这样做了:
-define(THIS_NODE, '[email protected]').
-define(THAT_NODE, '[email protected]').
然后我在
ERL_INETRC
环境变量中设置文件的位置:
export ERL_INETRC="$(pwd)/erl_inetrc"
net_adm:names()
命令处冻结。 然而,erl_epmd:names()
有效,这很奇怪,因为net_adm:names
应该调用erl_epmd:names
。
有人知道为什么
net_adm:names()
会冻结吗?
解决方案非常简单,但我是这样得出的:
主机名必须解析为 IP 地址。该文档并不完全清楚 但研究
net_adm:names()
代码证实了这一点。
WSL2 在具有 NAT 网络的虚拟机中运行,其中 IP 地址分配给 host 不是本域中本地路由器分配的主机。
当使用“短名称”时,一切都在本地主机上运行,这将始终解决 正确。对于“长名称”,主机名必须完全符合域和 FQDN 的要求 必须解析为 IP 地址。
我的
myoffice.loc
办公室网络地址是10.1.1.0/24。我的 WSL2 网络是 172.16.32.0/24。当 net_adm:names()
将 pandora.myoffice.loc
解析为 10.1.1.119 时,它无法绑定到 epmd
守护进程 使用的端口。但它没有报告任何错误,只是冻结了。
事实证明,将本地域设置为 DNS 中找不到的域会使所有主机解析为
127.0.0.1
的本地主机 IP。我不知道为什么,但它解决了我的问题。
所以我更改了本地配置文件
erl_inetrc
以使用不存在的域,
{domain, "wsl"}.
更改了我的测试脚本中的节点域,
-define(THIS_NODE, '[email protected]').
-define(THAT_NODE, '[email protected]').
使用 FQDN 启动我的分离节点,
erl -detached -noshell -name '[email protected]' -setcookie pandemic
一切都按预期进行:
{ok,[{"node1",37267},{"testnode",39771}]}
{ok,[{"node1",37267},{"testnode",39771}]}
pong
{20,1,55}
补充说明
erl_call
。erl_call -name '[email protected]' -c pandemic -q
。
但是,当我使用虚拟域名运行此命令时,它产生了错误:
erl_call: can't ei_gethostbyname(Pandora.wsl)
。
但是,使用短名称也可以使用相同的命令(如图):
erl_call -sname 'node1' -c pandemic -q
我无法让 WSL2 返回它分配给主机的 IP
[email protected]
。我找到了解决方法,但它显然只适用于
Erlang/OTP。
虽然我没有使用其中任何一个,但这里有一些网络解决方案显示出希望。