我的客户端需要连接到单个服务器进程。我正在使用UDP发现为客户端找到服务器。我有客户端和服务器交换IP地址和端口号,以便在完成发现后建立TCP / IP连接。这样,数据包大小保持很小。我看到这可以使用UDP以两种方式之一完成:
在1.如果有许多客户端,那么最初将传输许多多播消息(每个客户端一个)。只有服务器才会订阅并从客户端接收多播消息。一旦服务器响应客户端,客户端就不再发送多播消息。一旦所有客户端完成了对服务器的发现,就不会在网络上传输进一步的多播消息。但是,如果服务器关闭,则每个客户端将间隔发送多播消息信标,直到服务器备份并可以响应。
在2.只有服务器会定期提交多播消息信标。此消息最终将路由到订阅多播组的所有客户端。客户端收到数据包后,客户端的UDP侦听套接字将关闭,并且不再订阅多播组。但是,服务器必须继续发送多播信标,以便新客户端可以发现它。它将继续定期发送信标,无论客户是否有需要发现。
所以,无论如何,我都看到了利弊。在我看来,#1最初会导致更重的负载,但这个负载最终会降低到零。在#2中,服务器将继续永远发送信标。
UDP和多播对我来说是一个相当新的话题,所以我有兴趣找出哪种方法是首选方法,哪些方法可以减少网络负载。
答案 0 :(得分:4)
我过去曾多次使用选项#2。它适用于简单的网络拓扑。当UDP数据报超过以太网MTU时,我们确实看到了一些吞吐量问题,导致大量碎片。我们看到的最大问题是,由于许多路由器被配置为阻止多播流量,因此多播拓扑在较大的拓扑中发生故障。
在设计协议套件时,issue that Greg alluded to非常重要。只要您超越简单的网络拓扑,就必须找到address translation,IP spoofing的解决方案,以及与发现层到通信层的切换相关的许多其他问题。他们中的大多数都必须专门针对您的服务器如何识别自身并确保识别是客户可以使用的内容。
如果我能再做一遍(我们多少次说过这句话),我会寻找适合该法案并开始解决其他协议套件问题的基于标准的发现机制。你真正想要做的最后一件事是提出一个非常好的发现方案,在你部署它之后的一周,因为一些无法预料的网络拓扑。 Google service discovery
获取初始列表。我个人倾向于DNS-SD,但还有很多其他选择。
答案 1 :(得分:2)
我会推荐方法#2,因为很可能(取决于应用程序)你将拥有比服务器更多的客户端。通过让服务器发送信标,您只需每隔一段时间发送一个数据包,而不是每个客户端发送一个数据包。
此方法的另一个好处是,它使客户端更容易确定新服务器何时可用,或者现有服务器何时离开网络,因为它们不必维护与每个服务器的连接,或继续轮询每个服务器,找出答案。
答案 2 :(得分:1)
两者都是同样可行的方法。
方法#1的论点是,通常情况下,客户端会发起请求,服务器会监听并响应它们。
方法#2的论点是多播点是这样的,一个主机可以发送一个数据包,它可以被许多客户端接收(一对多),所以它的意思是#的反向1。
好吧,正如我想到的那样,我实际上已经被#2,服务器发起的信标所吸引。 #1的问题在于,假设客户端广播信标,并且它们与服务器连接,但服务器要么脱机或更改其IP地址。
当服务器备份并发送其第一个信标时,将同时通知所有客户端重新连接,并立即备份整个系统。对于#1,所有客户端都必须单独意识到服务器已经消失,并且它们将同时开始多播,直到与服务器连接回来。如果你有1000个客户端和1个服务器,你的网络负载实际上比方法#2大1000倍。
我知道这些消息很可能很小,一次只有1000个数据包对UDP网络没有任何意义,但从设计的角度来看,#2感觉更好。
编辑:我觉得我在这里正在发展一种分裂型人格障碍,但只是想到了为什么#1会成为优势的一个强有力的观点......如果你想要实施某种自然负载平衡或扩展到多个服务器,设计#1适用于此。这样,第一个“可用”服务器可以响应客户端的信标并连接到它,而不是#2,其中所有客户端都跳转到信标服务器。
答案 3 :(得分:1)
您的选项#2有一个很大的局限性,它假设服务器可以或多或少地直接与每个可能的客户端进行通信。根据您的操作系统的确切网络架构,情况可能并非如此。例如,您可能依赖于所有路由器和VPN软件以及WAN和NAT以及人们将网络连接在一起的任何其他内容,实际上可以处理多播信标数据包。
使用#1,您假设客户端可以向服务器发送UDP数据包。这是一个完全合理的期望,特别是考虑到客户端将要做的下一件事就是建立到同一服务器的TCP连接。
如果服务器出现故障且客户端想知道它何时备份,请确定使用exponential backoff,否则有一天你会因为数据包风暴而关闭网络! / p>