我正在编写我的第一个分布式erlang应用程序,我注意到我必须知道我的“服务”节点。如何在不知道运行哪个节点的情况下向我的服务发送请求?
基本上我想做这样的事情:
ReferenceToTheServiceProcess = locate(my_service).
ReferenceToTheServiceProcess ! {request, Stuff}.
或等效的其他东西(松耦合)。
谢谢!
答案 0 :(得分:8)
您可以使用全局名称注册服务流程,例如使用gproc
。这样你就不必知道你的服务当前所在的节点,你可能会看起来像你想要的那样。
答案 1 :(得分:3)
您可以使用global模块注册流程。 从您的服务流程调用:
global:register_name(my_service, self()).
向全局注册的流程调用发送消息:
Pid = global:whereis_name(my_service),
Pid ! {request, Stuff}.
或致电:
global:send(my_service, {request, Stuff}).
注册功能是原子的。 如果服务进程终止或节点发生故障,则名称将全局取消注册。
答案 2 :(得分:0)
或者,如果您仍想要本地注册流程,您可以编写如下内容:
where_is_service(Service) ->
lists:filter(fun(X) -> X =/= undefined end, [rpc:call(Node, erlang, whereis, [Service]) || Node <- [node() | nodes()]]).
此函数将结果返回本地(在节点上)引用的进程的pid为Service
此后,如果您只想运行第一个进程,请使用函数返回的列表:
send_msg_to_service(Service,Message) ->
case where_is_service(Service) of
[APid | _] -> APid ! Message, ok;
[] -> {error, service_not_running}
end.
希望这有帮助!