实际示例:TIBCO Rendezvous。
数据通过带有序列号的多播发送出去。检测到丢失序列号的客户端在多播组上发送消息“嘿,我错过了数据包 12345”。服务器重新多播该数据。服务器有一个可配置的数据量来缓冲,以防客户端请求它。
问题:
想象一下,有一个客户端丢弃了一半的数据包,还有 100 个健康的客户端。此客户端为每个其他数据包发送重传请求。服务器开始在其中一个健康的客户端上造成足够的负载,以致它开始丢弃数据包并请求重新传输。额外的负载会导致另一个健康的客户端开始请求重传。等等。拥塞崩溃的结果。
Tibco 提供了一种解决方法,即切断发送过多重传请求的订阅者。这使得单个用户更难导致拥塞崩溃。
限制拥塞崩溃风险的另一种解决方法是限制服务器愿意重新传输的数据量。
Tibco 还应该在客户端和服务器中提供关于是多播还是单播重传请求以及重传本身的启发式方法。他们没有。(对于服务器,如果在某个时间窗口内只有一个客户端请求它,您可以单播重传,对于客户端,如果服务器告诉您 - 在重传的数据包中 - 您是唯一一个请求的客户端,您可以单播重传请求重传并请在将来单播请求)
从根本上说,您必须在您希望保证客户端接收数据的强度与拥塞崩溃的风险之间做出决定。您将不得不猜测数据包被丢弃的位置以及重传是最有效地发送单播还是多播。如果服务器理解数据并且可以决定在无论如何要发送更新的数据时不发送重传(这使得重传无关紧要),那么您比 Tibco RV 等框架处于更好的位置。
有时理解数据会导致错误的假设。例如,市场数据——当有更新的报价时,最初似乎可以不重新传输报价。但稍后,您可能会发现订阅者保留了报价历史记录,而不仅仅是试图跟踪当前报价。也许您可能有不同的要求,具体取决于订阅者,有些客户端会更喜欢单播 TCP 和多播。
在某些时候,您需要在服务器上任意决定要缓冲多少数据,以防重传或客户端缓慢。