进程名,节点名!跨 Erlang 节点的消息 VS rpc:call/4 VS HTTP/1.1

Posted

技术标签:

【中文标题】进程名,节点名!跨 Erlang 节点的消息 VS rpc:call/4 VS HTTP/1.1【英文标题】: ProcessName, NodeName ! Message VS rpc:call/4 VS HTTP/1.1 across Erlang Nodes进程名,节点名!跨 Erlang 节点的消息 VS rpc:call/4 VS HTTP/1.1 【发布时间】:2012-11-08 06:46:24 【问题描述】:

我有一个设置,其中两个节点将进行大量通信。在节点 A 上,将有数千个进程用于访问节点 B 上的服务。两个节点之间将有大量的请求和响应。这两个节点将在两个不同的服务器上运行,每个服务器都在自己的硬件服务器上。

我有 3 个选项:HTTP/1.1、rpc:call/4 和直接向节点 B 上注册的 gen_server 发送消息。让我解释每个选项。HTTP/1.1 假设在节点 A 上,我有一个像 Ibrowse 这样的 HTTP 客户端,而在节点 B 上,我有一个像 Yaws-1.95 这样的 Web 服务器,该 Web 服务器能够处理无限连接,操作系统设置进行了调整,以允许 yaws 处理所有连接。然后让我在节点 A 上的进程使用 HTTP 进行通信。在这种情况下,每个方法调用都意味着一个 HTTP 请求和一个回复。我相信这里有开销,但我们正在评估这里的选项。称为webtool 的 erlang 内置机制可能是为此目的而构建的。 rpc:call/4 我可以简单地从节点 A 直接调用 rpc 到节点 B。我不太确定底层 rpc 机制是如何工作的,但我认为当两个 erlang 节点通过net_adm:ping/1 连接时,创建的连接不会关闭,但所有 rpc 调用都使用此管道传输请求并传递响应。请在此问题上更正我。从节点 A 向节点 B 发送消息我可以在节点 A 上创建进程,以便仅向已注册的节点发送消息进程,或节点 B 上的一组进程。这似乎也是一个干净的选择。 Q1. 对于两个 erlang 节点之间将始终进行大量通信的应用程序,您会推荐上述哪个选项以及为什么。想象一个消息传递系统,其中两个 erlang 节点是路由器 :) ?Q2. 上述哪种方法更干净、问题更少并且更容错(我的意思是这里也就是说,该方法不应该有单点故障,这可能导致节点 A 上的所有进程都失明)? Q3. 您选择的机制:您将如何使其更具容错性或冗余性? 假设: 节点始终处于活动状态,永远不会宕机,节点之间的网络连接将始终可用且不拥塞(仅专用于两个节点),操作系统已为这两个节点分配了最大的资源。感谢您的评价

【问题讨论】:

我之前也问过类似的问题。 ***.com/questions/12508539/… 当语言本身提供了一些解决方案时,我认为使用 http 不是一个好主意。 HTTP api 可能效率较低。 【参考方案1】:

HTTP 肯定过时了。只是创建新连接的往返开销是个问题。

对于 Erlang 连接和使用 Pids,您的优势在于可以订阅节点关闭消息并处理节点关闭的情况。单个 TCP 连接应该能够为您提供非常快的速度,但是请注意,它的工作原理就像一个长管道:消息在管道上混合和解复用,这可能会影响线路上的延迟。这也意味着大消息会阻止小消息通过。

您的目标带宽是多少,延迟是多少?回复消息的第 95 和 99 个百分位数是多少?最好提出一些粗略的数字,然后尝试针对这些数字,而不是仅仅“尽可能快”。首先设定你的成功标准。

【讨论】:

谢谢@I+GIVE+CRAP+ANSWERS【参考方案2】:

Q1:在我看来,HTTP 会增加额外的开销并且不会给您带来任何好处。如果您正在设计 REST API,HTTP 会很有用。就开销而言,直接发送消息和 rpc:call 看起来差不多。

Q2:发送消息更加清晰。这是erlang的设计方式。对于 RPC 调用,您必须始终跟踪哪个调用在何处以及在何种情况下执行,如果两台服务器都有状态,这可能是一个大问题。 RPC 调用也是同步的。

Q3:如果我能承受较小的开销,我会使用 UBF,否则我会直接在 erlang 节点之间发送消息。如果带宽是一个问题,则还需要其他技巧。就像以相同的方式对消息进行编码,然后使用一些压缩算法来减小消息的大小,或者我可以完全放弃 erlang 消息传递并使用 UDP 套接字。

【讨论】:

【参考方案3】:

这不是很明显!是最好的方法。当然,它是最简单的,代码也将是最优雅的。

在可扩展性方面,请考虑使用 rpc/!你必须维护一个 erlang 集群。我发现即使在私有云中只有 10-20 个节点也很痛苦。我永远不会推荐更大的部署,例如EC2,其中 io/latency/network 不是确定性的。

我建议以一种可以让您在未来交换通信引擎的方式来构建项目。 HTTP 也很繁重,但有一些选择:

socket-socket (tcp/udp/sctp) amqp(与负载平衡相关的许多好处) zeromq(甚至比 amqp 更好)

投注 !/rpc 和 OTP 集群是有风险的。您将与全网状开销、主选举算法和仲裁/分区检测作斗争。

【讨论】:

np, ..不要误会我的意思。拥有 100 多个节点的集群很容易。它不是免费的。

以上是关于进程名,节点名!跨 Erlang 节点的消息 VS rpc:call/4 VS HTTP/1.1的主要内容,如果未能解决你的问题,请参考以下文章

Erlang epmd官方文档中文翻译

ORACLE RAC 的启动和关闭顺序

无法解析主机名 git:提供节点名或服务名,或未知

如何获取当前节点的父节点名?

getaddrinfo:提供节点名或服务名,或未知

C# 如何得到一XML文件中指定的节点属性值