我可以从远程节点调用 GenServer 客户端函数吗?

Can I call GenServer client functions from a remote node?

我在远程节点上有一个 GenServer,模块中有实现和客户端功能。我能以某种方式远程使用 GenServer 客户端功能吗?

使用 GenServer.call({RemoteProcessName, :"app@remoteNode"}, :get) 可以达到我的预期,但是很麻烦。

如果我想清理它,我认为必须在调用(客户端)节点上编写客户端函数是否正确?

您可以使用 :rpc.call/{4,5} 函数。

:rpc.call(:"app@remoteNode", MyModule, :some_func, [arg1, arg2])

来电较多时,最好用gen_server:call/2-3
如果你想使用rpc:call/4-5,你应该知道它只是在每个节点上一个名为rex的进程来处理所有请求。所以如果是运行一个Mod:Func(Arg1, Arg2, Argn),此时不能响应其他请求!

TL;DR

讨论

有PID、消息、监视器和链接。仅此而已。那就是你的宇宙。 (除非您深入了解运行时实现的一些相当深奥的方面——但在 EVM 语言表示的抽象级别上,前面所述的元素(应该)构成了您的宇宙。)

在 Erlang 环境中(无论是本地还是分布在网格中)任何 PID 可以发送消息给任何其他 PID(不需要中间人),以及建立监控等等。

gen_server:cast 发送 gen_server 打包消息(因此它将以 handle_cast/2 将被调用的形式到达)。 gen_server:call/2 建立监视器和超时以接收标记的回复。简单地做 PID ! SomeMessagegen_server:cast(发送消息)本质上是一样的,没有任何背后的 gen_server 机制(更难抽象为接口)。

仅此而已。

考虑到这一点,当然您可以跨节点使用 gen_server:call/2,只要它们通过 disterl 连接到 cluster/mesh。两个断开连接的节点将不得不以不同的方式(网络套接字)进行通信,并且不会知道彼此的 PID 内部映射,但只要使用 disterl,它们就会很容易地相互转换 PID。命名进程是事情变得有点棘手的地方,但这是 global 模块和实用程序(例如 gproc 的目的(尽管对此类设施的依赖超过某一点通常表明存在体系结构问题).

当然,仅仅因为来自任何节点的 PID 可以与来自另一个节点的 PID 通信并不总是意味着它们 应该 。当您开始发送高频或大型消息(很多 gen_server:calls)时,网络的物理拓扑(带宽、延迟、抖动)开始发挥作用,并且您总是必须考虑分区容错性——但是为了减轻繁重的工作(很少见)或在一个非常大的系统中对子系统进行物理分区(更常见),直接发送消息是一种非常简单的方法,可以将为单个节点编码的程序分发到集群中。

(考虑到所有这些,很少看到使用 rpc 模块。)