9

我有需要全部连接到单个服务器进程的客户端。我正在为客户端使用 UDP 发现来查找服务器。我让客户端和服务器交换IP地址和端口号,以便在发现完成后建立TCP/IP连接。这样,数据包的大小就可以保持很小。我看到这可以使用 UDP 以两种方式之一完成:

  1. 每个客户端发送自己的多播消息以搜索服务器,然后服务器对其进行响应。客户端可以定期(在服务器关闭的情况下)重复发送此多播消息,直到服务器响应。
  2. 服务器定期发送多播消息信标。客户端订阅多播组,从而接收到服务器的多播消息并完成发现。

1. 如果有很多客户端,那么最初会传输许多多播消息(每个客户端一个)。只有服务器会订阅和接收来自客户端的多播消息。一旦服务器响应客户端,客户端停止发送多播消息。一旦所有客户端都完成了对服务器的发现,就不会再在网络上传输多播消息。但是,如果服务器已关闭,则每个客户端将间隔发送多播消息信标,直到服务器备份并可以响应。

2. 只有服务器会定期提交多播消息信标。该消息最终会被路由到订阅多播组的所有客户端。一旦客户端收到数据包,客户端的 UDP 侦听套接字就会关闭,并且它们不再订阅多播组。但是,服务器必须继续发送多播信标,以便新客户端可以发现它。它会继续定期发送信标,无论是否有任何客户端需要发现。

所以,无论哪种方式,我都看到了利弊。在我看来,#1 最初会导致更重的负载,但这个负载最终会减少到零。在#2中,服务器将永远继续发送信标。

UDP 和多播对我来说是一个相当新的话题,所以我有兴趣找出哪种方法是首选方法,哪种方法可以减少网络负载。

4

4 回答 4

4

我过去几次使用过选项#2。它适用于简单的网络拓扑。当 UDP 数据报超过以太网 MTU 导致大量碎片时,我们确实看到了一些吞吐量问题。我们看到的最大问题是,由于许多路由器被配置为阻止多播流量,因此多播发现在较大的拓扑中会失效。

在设计协议套件时,Greg 提到的问题非常重要。一旦您超越了简单的网络拓扑,您就必须找到地址转换IP 欺骗以及与从发现层到通信层的切换相关的一系列其他问题的解决方案。它们中的大多数都与您的服务器如何标识自己以及确保标识是客户端可以使用的东西有关。

如果我可以再做一遍(我们说过多少次这个短语),我会寻找符合要求的基于标准的发现机制并开始解决其他协议套件问题。您真正想做的最后一件事是提出一个非常好的发现方案,该方案在您部署它后的一周内因某些不可预见的网络拓扑而中断。谷歌service discovery的起始名单。我个人倾向于使用 DNS-SD,但还有很多其他选项可用。

于 2009-07-30T12:02:17.237 回答
2

我会推荐方法#2,因为很可能(取决于应用程序)您将拥有比服务器多得多的客户端。通过让服务器发送信标,您每隔一段时间只发送一个数据包,而不是为每个客户端发送一个数据包。

这种方法的另一个好处是,它使客户端更容易确定新服务器何时可用,或者现有服务器何时离开网络,因为它们不必维护与每个服务器的连接,或者保持轮询每个服务器,找出答案。

于 2009-07-30T04:06:57.783 回答
2

两者都是同样可行的方法。

方法#1 的论点是,在正常原则下,客户端发起请求,服务器监听并响应它们。

方法#2 的论点是多播的目的是让一台主机可以发送一个数据包,并且它可以被许多客户端(一对多)接收,因此它与#1 相反。

好的,当我想到这一点时,我实际上被#2,服务器启动的信标所吸引。#1 的问题是,假设客户端广播信标,它们与服务器连接,但服务器要么离线,要么更改其 IP 地址。

当服务器备份并发送它的第一个信标时,将同时通知所有客户端重新连接,并且您的整个系统会立即备份。使用#1,所有客户端都必须单独意识到服务器已经消失,并且它们都将同时开始多播,直到与服务器重新连接。如果您有 1000 个客户端和 1 个服务器,那么您的网络负载实际上是方法 #2 的 1000 倍。

我知道这些消息很可能很小,一次 1000 个数据包对 UDP 网络来说不算什么,但从设计的角度来看 #2 感觉更好。

编辑:我觉得我在这里发展了一种人格分裂症,但只是想到了为什么#1 会是一个优势的一个强有力的观点......如果你想要实现某种自然的负载平衡或多个扩展服务器,设计#1 很适合这个。这样,第一个“可用”服务器可以响应客户端的信标并连接到它,而不是所有客户端都跳转到信标服务器的#2。

于 2009-07-30T04:21:24.623 回答
1

您的选项#2 有一个很大的限制,因为它假定服务器可以或多或少地直接与每个可能的客户端通信。根据您的操作系统的确切网络架构,情况可能并非如此。例如,您可能依赖于所有路由器和 VPN 软件以及 WAN 和 NAT 以及人们将网络连接在一起的任何其他东西,实际上可以处理多播信标数据包。

使用#1,您假设客户端可以向服务器发送 UDP 数据包。这是一个完全合理的预期,尤其是考虑到客户端接下来要做的就是与同一台服务器建立 TCP 连接。

如果服务器宕机而客户端想知道它何时恢复,请务必使用指数退避,否则有一天您将因数据包风暴而导致网络瘫痪!

于 2009-07-30T04:34:02.840 回答