这么多持久连接到服务器。那是正确的方法吗?

So many persistent connections to the server. Is that the right way?

我想更好地了解具有大量用户群的网络服务,以便我知道如何处理我正在忙的项目。

我的以下陈述可能不正确,但它们仍然引出了我想问的问题...

请考虑 Skype 和 TeamViewer 客户端。似乎两者都保持对各自服务器开放的持久网络连接。他们使用这些持久连接来发起额外的连接。如果客户端位于 NAT 后面,则其中一些连接是通过打孔创建的。然后将它们用于直接对等通信。

根据 http://expandedramblings.com/index.php/skype-statistics/ 现在有 3 亿用户使用 Skype,每日活跃用户为 490 万。我假设这 490 万用户中的大多数人很可能会在一天中的大部分时间使用他们的客户端应用程序 运行。这是在任何给定时间打开的 Skype 服务器的大量连接。

所以对于我的问题;这可行或至少可以接受吗?我的意思是,在空闲时不打开网络连接不是更好吗,尤其是当有这么多连接同时打开到服务器时?我能想到的唯一原因是,这将是正确进行打孔的唯一方法。从技术上讲,这是如何在服务器端实现的?

Is this feasible or at least acceptable?

当然是可行的,你已经提到了两个流行的应用程序,所以它在实践中是非常可行的。

至于可接受,没有互联网权威机构(例如 IETF)曾经说过即使在低流量下也有长期连接是不可接受的。

此外,唯一重要的组件是保持 connection/flow 状态的网络元素。这些肯定是端点和所谓的中间盒,如 NAT 和防火墙。对于客户端这只是一个连接,服务器通常由应用程序开发人员(做出此选择的人)自己微调,因此对于这些来说这是可以接受的。对于 middleboxes 来说很简单:它们别无选择,它们被设计为只适用于所有类型的流,包括长期持久连接。

I mean, wouldn't it be better to not have a network connection open while idle and aspecially when there are so many connections open to the servers at once?

完全没有。首先,这可能会 'much' 慢,因为您需要在每次控制平面调用之前建立一个完整的连接。如果您的 RTT 很大,或者如果服务器为了 load-balancing/localization 目的进行一些复杂的连接 proxying/redirection,这一点尤其明显。

此外,这在历史上会使大量用户难以来电。许多 ISP block/blocked 未知通过防火墙从 Internet 传入的连接。类似地,如果您位于不支持 UPnP 或 PCP 的 NAT 设备后面,您将无法打开端口来侦听您的 public IP 地址。所以除了打孔你还需要它。

The only reason I can think is that it would be the only way to properly do Hole Punching. Techically, how is this achieved on the server side?

从技术上讲,一旦 NAT 设备保持完整的 <src-ip,src-port,dest-ip,dest-port,protocol>(经典 5 元组)流匹配,您就无法进行适当的打孔。那么你可以用 'hole punching' 做的最好的事情就是在对等点之间设置一个代理。

打洞依赖的是 NAT 流量查找只查看 <src-ip,src-port,protocol> 上游和 <dest-ip,dest-port,protocol> 下游来进行转换。在那种情况下,两个客户端都只是建立到服务器的连接,他们的 ip 和端口被转换,服务器将其传递给另一个客户端。另一个客户端现在可以开始向转换后的 <ip,port> 组合发送数据包,这应该可以工作,因为 NAT 忽略了服务器的 ip/port。但是即使特定的 NAT 会像这样工作,某些安全设备(例如状态防火墙)也可能会检测到会话劫持并丢弃它。

现在您宁愿使用 UPnP 打开一个端口来侦听您的 public IP,如果支持的话会容易得多。