Ang*_*ker 18 c# architecture p2p
对于许多人将在办公室使用的应用程序,我有以下要求 - 没有服务器组件.客户端应用程序的所有实例都应以某种方式在它们之间进行协商,以确定哪个客户端将承担服务器角色.客户应该通过IP在他们之间进行通信.
如果客户端应用程序出现故障,另一个客户端必须以无缝方式接管.我知道拥有一台服务器会更简单.但是因为应用程序必须非常有弹性,所以不想让服务器停机(甚至是其备份)的风险,而是依赖于这种混合网状连接,其中服务器角色从客户端跳到客户端.
我想我的应用程序连接已关闭.基本上,当应用程序启动时,它会通过UDP(通过预定义的IP地址,所有内容监听或通过UDP广播)宣布自己.从那时起,通信以类似的方式进行.
我遇到问题的部分是如何在客户端之间进行协商/自组织以选择具有服务器角色的客户端.如何可靠地检测到客户端已经关闭,然后必须进行新的协商.最后的困难是复制客户端使用服务器角色累积的数据.
我在c#中创建了一个原型,用于通信并尝试复制数据,但协商部分(特别是与客户端故障相结合).
最初我认为这就是ZeroConf(又名Bonjour)所做的.但那只是宣布可用的网络服务.
无论如何,我不想重新发明,我不能成为第一个想要这样做的人.所以我的问题:
在一组机器中选择服务器,无论这些机器是否也是客户机,都是一个非常重要的问题.这被称为领导人选举.您应该阅读的开创性工作是Leslie Lamport的The Part Time Parliament,它描述了Paxos协议.Google利用Paxos开发了一个名为Chubby的系统,该系统可以满足您的需求.
也就是说,你应该看看像Apache ZooKeeper这样的系统,它是分布式领导者选举的开源(虽然是Java)实现,更广泛地说,是在大量负载下经过全面测试的分布式锁管理.在Hadoop的分布式数据存储和计算平台,特别HBase的,是在Hadoop上运行的分布式数据库,使大量使用的ZooKeeper的决定"谁说了算"当中一组服务器.这样他们中的任何一个都可能会失败,而其他人则决定谁接管了这份工作.
正如我前面提到的,领导人选举充满了错误.做对很难.我已经在C#中实现了paxos"for fun"六次,并且我的所有实现都有bug.
因此,您当前拥有一个系统,其中 LAN 上的每个客户端都将通过 UDP 向 LAN 的其余部分通告自己。其中一个客户端应用程序是“服务器”,除了本身是客户端之外,还具有一些额外的命令和控制能力。
可以肯定的是,这并不是一个新想法。您想要的是在最初的“我在这里”连接通信期间添加一些额外的对话。当新客户端向 LAN 的其余部分大喊“我在这里”时,如果有服务器,服务器应该说“欢迎,我是服务器”,并且新客户端应用程序现在知道哪个客户端充当客户端服务器。所有其他客户可能也应该说“嗨”。如果没有服务器,新客户端应该首先重复“hello”(毕竟是UDP;你必须预期某些消息不会被接收到),如果没有人响应,则这个新客户端是唯一的网络,默认为“服务器”。如果有其他服务器但没有人声称自己是服务器,则客户端可以“相互讨论”来确定新服务器。
除此之外,服务器副本应该定期(也许每 3-5 秒)向每个人喊出“我还在这里”;这称为“心跳”消息,是双向“ping”验证方法的一种非常常见的替代方法。
如果服务器应用程序(或任何副本,实际上)正常关闭,它应该大喊“再见大家,弄清楚谁是下一个服务器”。剩下的客户可以互相讨论。如果充当服务器的客户端崩溃,客户端将错过服务器的“心跳”消息,询问“谁是服务器”,如果仍然没有人响应,客户端将相互讨论。
现在,客户“相互讨论”可以像您喜欢的那样简单或复杂。最简单的是,无论哪个客户端说“好吧,我现在是服务器”,就成为服务器。您可能必须在消息中包含某种时间,以便如果另一台计算机同时说出该消息,则客户端可以说“好吧,客户端 15 先说了,所以我们和他一起说”。客户可以“投票”;让每个客户端与所有其他客户端通信,以确定该客户端与所有其他客户端之间的标称延迟,并且该客户端将“投票”最低延迟的连接(任何客户端都不能为自己投票,除非它发现自己是唯一的连接)。多数票获胜。
或者,服务器可以作为其“心跳”消息的一部分,说“如果我宕机,我的继任者是客户端 X”;如果心跳丢失并且随后来自客户端的“你还在吗,服务器”消息没有得到响应,客户端可以说“国王死了!国王客户端X万岁!”。
要明白,全客户端系统中的这一治理层在选择“权威”客户端作为服务器时必然会显着增加客户端通信的复杂性。此外,虽然您使用 UDP 协议可以实现快速通信,但 UDP 消息始终会发生冲突;如果你和另一个人在说话,你们的信息就会发生冲突。因此,我建议在该软件中的大多数通信中使用 TCP 而不是 UDP,因为在该软件中需要听到特定客户端的声音。这是对客户端的任何直接询问(“服务器,你还在吗?”),无论你使用什么过程让客户端决定谁是新服务器,等等。
| 归档时间: |
|
| 查看次数: |
1548 次 |
| 最近记录: |