这是为多客户端应用程序构建Erlang网络服务器的正确方法吗



我正在使用Erlang为多人棋盘游戏构建一个小型网络服务器。该网络服务器使用Mnesia DB的本地实例为每个连接的客户端应用程序存储会话。在存储在本地Mnesia中的每个客户端的记录(会话)中,我存储客户端的PID和NODE(客户端登录的节点)。

我计划在至少2个连接的服务器(节点A&B)上部署这个网络服务器。因此,为了允许登录在节点a上的客户端a搜索(向Mnesia查询)登录在节点B上的客户端B,我将Mnesia会话表从节点a复制到节点B,反之亦然。

客户端A查询客户端B的PID和NODE后,客户端A和客户端B可以直接通信。

这是在登录到两个不同Erlang节点的两个客户端应用程序之间建立连接的正确方法吗

根据定义,创建一个两个或多个节点完全同步的系统是不可能的。然而,在实践中,你可能会离得足够近,它可以解决你的特定问题。

您没有说明在两个节点上运行的确切原因,所以我认为这是为了可扩展性。有了许多节点,如果你做对了,你的系统也会变得更可用和容错。然而,如果你知道你只会在一个节点中运行,并且在主节点不可用的情况下需要另一个节点作为热从节点来接管,那么这个问题可以简化。

要在两个不同节点上的两个进程之间建立连接,需要一些全局寻址(用户id 123是pid<123456,0>)。如果您还关心一次只为用户A运行一个进程,则还需要锁定或只允许唯一的寻址注册。如果您也想增长,您需要一种添加更多节点的方法,无论是在系统运行时还是在系统停止时。

现在,已经有一些解决方案可以帮助解决您的问题,并进行不同的权衡:

  • gproc在全局模式下,允许在给定的密钥下注册进程(这可以为您提供寻址和锁定)。它分布在整个集群中,没有单点故障,但领导者选举(至少在我上次查看时)只适用于系统启动时可用的节点。添加新节点需要gen_leader的实验版本或停止系统。在你自己的代码中,如果你知道两个玩家只会互相交谈,你可以在同一个节点上启动他们。

  • riak_core,允许您在riakKV和riak搜索中使用的经过充分测试和验证的架构之上进行构建。它以一种允许您添加新节点并重新分发密钥的方式将密钥映射到存储桶中。您可以插入此机制并移动流程。这种方法不能让你决定从哪里开始你的流程,所以如果你在他们之间有很多沟通,这将通过网络进行。

  • 将mnesia与分布式事务一起使用,可以确保每个节点在提交事务之前都有数据,这将为您提供寻址和锁定的分布,但除此之外,您还必须执行其他所有操作(如释放锁定)。注意:我从未在生产中使用过分布式事务,所以我无法告诉您它们的可靠性。此外,由于是分布式的,预计会有延迟。注意2:您应该检查如何添加更多节点并复制表,例如,如果可以在不停止记忆的情况下进行复制。

  • Zookeper/doozer/roll您自己的,提供了一个集中的高可用数据库,您可以使用它来存储地址。在这种情况下,您需要自己处理注销。从寻址的角度来看,在系统运行时添加节点很容易,但您需要一些方法让应用程序了解新节点并开始在那里生成进程。

此外,没有必要存储节点,因为pid包含足够的信息,可以将消息直接发送到正确的节点。

作为一个很酷的技巧,您可能已经知道,pid可能会被序列化(就像VM中所有数据一样)为二进制文件。使用term_to_binary/1binary_to_term/1在VM内的实际pid和二进制文件之间进行转换,您可以将二进制文件存储在任何接受二进制数据的文件中,而不会以某种愚蠢的方式对其进行篡改。

相关内容

最新更新