许多像Caplin这样的Comet实现都提供了服务器可扩展的解决方案。
以下是Caplin网站的统计数据之一:
Caplin liberator的单个实例最多可支持100000个客户端,每个客户端每秒接收1条消息,平均延迟小于7ms
这与任何网络服务器上的HTML5 websocket相比如何?有人能给我指一下HTML5 websockets的统计数据吗?
披露-我为Caplin工作。
这个页面上有一些错误信息,所以我想试着让它更清楚。。
我认为我们可以把我们正在讨论的方法分成三个阵营。。
- Comet HTTP轮询-包括长轮询
- Comet HTTP流-服务器到客户端的消息在初始设置后使用单个持久套接字,没有HTTP头开销
- Comet WebSocket-单个双向套接字
我认为它们都是Comet,因为Comet只是一种范式,但自从WebSocket出现以来,有些人想把它当作不同的东西来对待,或者取代Comet——但这只是另一种技术——除非你乐于只支持最新的浏览器,否则你不能只依赖WebSocket。
就性能而言,大多数基准测试都集中在服务器到客户端的消息上——用户数量、每秒消息数量以及这些消息的延迟。在这种情况下,HTTPStreaming和WebSocket之间没有根本区别——它们都是在一个开放的套接字中编写消息,几乎没有或根本没有头或开销。
如果消息频率较低,长轮询可以提供良好的延迟。但是,如果您连续收到两条消息(服务器到客户端),那么在收到第一条消息后发出新请求之前,第二条消息不会到达客户端。
我想有人接触了HTTPKeepAlive。这显然可以改进Long轮询——您仍然有往返和标头的开销,但并不总是创建套接字。
在有更多客户端到服务器消息的场景中,WebSocket应该改进HTTP流。与每个人都能理解的简单易懂的"向很多客户发送大量消息"相比,将这些场景与现实世界联系起来会产生稍微更随意的设置。例如,在一个交易应用程序中,创建一个包含执行交易的用户的场景(即客户端到服务器的消息)很容易,但结果比基本的服务器到客户端场景更有意义。交易员并不试图每秒进行100次交易,所以你最终会得到这样的结果:"10000名用户每秒收到100条消息,同时每5分钟发送一次客户端消息"。客户端到服务器消息更有趣的部分是延迟,因为与服务器到客户端消息相比,所需的消息数量通常微不足道。
上面有人提出的另一点,关于64k客户端,除了配置数字文件描述符等,你不需要做任何聪明的事情来支持服务器上超过64k的套接字,并且你可以很好地达到64k以上的套接字。
理论上,WebSockets可以比HTTP更好地扩展,但也有一些注意事项和解决这些注意事项的方法。
HTTP和WebSockets的握手头处理的复杂性大致相同。HTTP(和最初的WebSocket)握手可以很容易地超过1K的数据(由于cookie等)。重要的区别在于HTTP握手在每个消息中都会再次发生。一旦建立了WebSocket连接,每条消息的开销只有2-14个字节。
@David Titarenco的回答(1,2)中发布的优秀Jetty基准测试链接表明,与Comet相比,WebSockets可以轻松实现超过数量级的更好延迟。
有关WebSockets与HTTP的伸缩性的更多信息,请参阅此答案。
注意事项:
-
WebSocket连接是长寿命的,不像HTTP连接是长寿的。这大大减少了开销(没有为每个请求/响应创建和管理套接字),但这确实意味着,要将服务器扩展到64k以上,需要在同一服务器上使用多个IP地址等技巧。
-
由于web中介的安全问题,浏览器到服务器的WebSocket消息对所有负载数据进行XOR屏蔽。这为服务器解码消息增加了一些CPU利用率。然而,XOR是大多数CPU体系结构中最有效的操作之一,并且通常有硬件辅助。服务器到浏览器的消息没有被屏蔽,因为WebSocket的许多使用不需要从浏览器到服务器发送大量数据,所以这不是什么大问题。
很难知道这与任何东西相比如何,因为我们不知道(平均)负载大小有多大。在引擎盖下(就像服务器的实现方式一样),HTTP流和websocket实际上是相同的-除了最初的握手,使用HTTP时握手显然更复杂。
如果你用C(ala Caplin)编写自己的websocket服务器,你可能会毫不费力地达到这些数字。大多数websocket实现都是通过现有的服务器包(如Jetty)完成的,因此这种比较并不公平。
一些基准:
http://webtide.intalio.com/2011/09/cometd-2-4-0-websocket-benchmarks/
http://webtide.intalio.com/2011/08/prelim-cometd-websocket-benchmarks/
然而,如果您查看C事件库基准测试,如libev和libevent,这些数字看起来更性感:
http://libev.schmorp.de/bench.html
忽略任何形式的轮询,正如其他地方所解释的,当更新率高时,都会引入延迟,JavaScript流媒体最常见的三种技术是:
- WebSocket
- 彗星XHR/XDR流
- Comet Forever IFrame
WebSocket是迄今为止最干净的解决方案,但在浏览器和网络基础设施方面仍然存在不支持它的问题。它越早被依赖越好。
XHR/XDR&Forever IFrame都可以从服务器向客户端推送数据,但需要进行各种破解才能在所有浏览器中一致工作。根据我的经验,这些Comet方法总是比WebSockets稍微慢一点,尤其是因为它需要更多的客户端JavaScript代码才能工作——然而,从服务器的角度来看,通过有线发送数据的速度是相同的。
下面是更多的WebSocket基准图,这次是为我们的产品我的Channels Nirvana。
跳过多播和二进制数据图,一直跳到页面上的最后一个图(JavaScript高更新率)
总之,结果显示Nirvana WebSocket以800微秒的延迟向2500k用户每秒提供50个事件。在5000个用户(总共250k个事件/秒流式传输)时,延迟为2毫秒。