0

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

我有 3 个选项: HTTP/1.1 、 rpc:call/4 和直接向节点 B 上注册的 gen_server 发送消息。让我解释每个选项。

HTTP/1.1

假设在节点 A 上,我有一个类似 HTTP 客户端Ibrowse,在节点 B 上,我有一个类似 Web 服务器Yaws-1.95,Web 服务器能够处理无限连接,操作系统设置调整为允许 yaws 处理所有连接. 然后让我在节点 A 上的进程使用 HTTP 进行通信。在这种情况下,每个方法调用都意味着一个 HTTP 请求和一个回复。我相信这里有开销,但我们正在评估这里的选项。称为 erlang 的内置机制webtool,可能就是为了这种目的而构建的。

RPC:调用/4

我可以直接从节点 A 到节点 B 进行 rpc 调用。我不太确定底层 rpc 机制是如何工作的,但我认为当两个 erlang 节点通过连接时net_adm:ping/1,创建的连接不会关闭,但所有 rpc 调用都使用这个管道传输请求并传递响应。请纠正我这一点。

从节点 A 向节点 B 发送消息

我可以让节点 A 上的进程只向已注册的进程或节点 B 上的一组进程发送消息。这似乎也是一个干净的选择。

Q1。对于两个 erlang 节点将一直在它们之间进行大量通信的应用程序,您会推荐上述哪个选项以及为什么。想象一个消息传递系统,其中两个 erlang 节点是路由器 :) ?

Q2。上述哪种方法更干净、问题更少并且更容错(我的意思是,该方法不应该有单点故障,这可能导致节点 A 上的所有进程都失灵)?

Q3。您选择的机制:您将如何使其更具容错性或冗余性?

假设:节点始终处于活动状态并且永远不会关闭,节点之间的网络连接将始终可用且不拥塞(仅专用于两个节点),操作系统已为这两个节点分配了最大的资源。

感谢您的评价

4

3 回答 3

3

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

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

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

于 2012-11-08T13:45:17.540 回答
2

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

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

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

于 2012-11-08T10:08:58.370 回答
1

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

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

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

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

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

于 2012-11-08T18:24:42.933 回答