HTML WebSockets是否为每个客户端维护一个开放的连接?可以缩放吗?


159

我很好奇是否有人知道HTML WebSockets的可伸缩性。对于我阅读的所有内容,似乎每个客户端都将与服务器保持一条开放的通讯线路。我只是想知道它如何扩展以及服务器可以处理多少个打开的WebSocket连接。也许将这些连接保持打开状态在现实中不是问题,但感觉确实是这样。


1
没有HTML WebSocket这样的东西。您的意思是HTTP WebSocket。
罗恩侯爵,

Answers:


209

在大多数情况下,WebSockets的伸缩性可能会优于AJAX / HTML请求。但是,这并不意味着WebSockets可以替代AJAX / HTML的所有用法。

就其本身而言,每个TCP连接消耗的服务器资源非常少。通常,建立连接可能很昂贵,但保持空闲连接几乎是免费的。通常遇到的第一个限制是可以同时打开的文件描述符的最大数量(套接字消耗文件描述符)。这通常默认为1024,但可以轻松配置为更高。

是否曾经尝试过配置Web服务器以支持成千上万的同时AJAX客户端?将那些客户端更改为WebSockets客户端,这可能是可行的。

HTTP连接虽然不会长时间创建打开文件或不占用端口号,但在几乎所有其他方式上都更昂贵:

  • 每个HTTP连接都会携带很多在大多数时间都不使用的包包:Cookie,内容类型,临时长度,用户代理,服务器ID,日期,最后修改时间等。建立WebSockets连接后,只有应用程序所需的数据需要来回发送。

  • 通常,HTTP服务器配置为记录每个HTTP请求的开始和完成,这会占用磁盘和CPU时间。记录WebSockets数据的开始和完成将成为标准,但是进行双工传输的WebSockets连接不会有任何额外的日志记录开销(如果应用程序/服务被设计为这样做的话)。

  • 通常,使用AJAX的交互式应用程序会连续轮询或使用某种长轮询机制。WebSockets是一种更简洁(且资源更少)的方式,可以处理更多事件的模型,在这种情况下,服务器和客户端在可以通过现有连接进行报告时可以互相通知。

  • 生产中大多数流行的Web服务器都具有用于处理HTTP请求的进程(或线程)池。随着压力的增加,池的大小将增加,因为每个进程/线程一次处理一个HTTP请求。每个额外的进程/线程都使用更多的内存,并且创建新的进程/线程比创建新的套接字连接(这些进程/线程仍然必须这样做)要昂贵得多。大多数流行的WebSockets服务器框架都采用事件路由,这种路由倾向于扩展并具有更好的性能。

WebSockets的主要好处将是减少交互式Web应用程序的延迟连接。与HTTP AJAX /长轮询(假定应用程序/服务器设计正确)相比,它将更好地扩展并且消耗更少的服务器资源,但是IMO较低的延迟是WebSockets的主要优势,因为它将启用不可能的新型Web应用程序当前的开销和AJAX /长轮询的延迟时间。

一旦WebSockets标准更加最终确定并具有更广泛的支持,便有必要将其用于需要与服务器频繁通信的大多数新的交互式Web应用程序。对于现有的交互式Web应用程序,这实际上取决于当前AJAX /长轮询模型的运行状况。转换工作并非易事,因此在许多情况下,付出的代价是不值得的。

更新

有用的链接:使用Node.js在AWS上进行60万个并发Websocket连接


4
很棒的分析服务。感谢您抽出宝贵的时间来回复。
瑞安·蒙哥马利

7
但是,一旦碰到墙,我仍然不知道如何缩放。的确,WebSocket消耗的资源更少(它们可以垂直扩展),但是HTTP对于水平扩展非常有用。从理论上讲,我可以添加服务器以无限扩展。当您用完一个盒子的容量后,我一直对如何扩展感到困惑。有什么想法吗?
肖恩·克拉克·赫斯

6
@Sean。WebSockets在水平扩展方面不一定会更糟。它只是打开不一定容易扩展的新应用程序。例如,为了提供静态数据,一堆WebSocket服务器的伸缩能力将比一堆HTTP服务器好(或更好)。无论传输方式如何,低延迟的实时游戏都很难扩展(使用HTTP实在不可行)。真正的问题是数据/应用程序扩展的程度。如果可以扩展,那么您对HTTP与WebSocket的选择应基于其他因素:延迟,部署选项,浏览器支持等
。– kanaka

2
一种更正-TCP连接由目标ip和目标端口组成。这意味着±64k端口限制实际上仅适用于单个客户端。从理论上讲,服务器可以具有任意数量的打开连接,仅受其硬件限制。
Rizon 2013年

@Rizon,是的。我已经更新了答案并更改了开放端口限制,而是提到了文件描述符限制,这是人们经常首先遇到的限制。
kanaka

36

需要澄清的是:在这种情况下,服务器可以支持的客户端连接数与端口无关,因为服务器(通常)仅在单个端口上侦听WS / WSS连接。我认为其他评论者要引用的是文件描述符。您可以将文件描述符的最大数量设置得很高,但是您必须注意每个打开的TCP / IP套接字的套接字缓冲区大小之和。这是一些其他信息:https : //serverfault.com/questions/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

至于通过WS和HTTP减少的延迟,这是事实,因为除了最初的WS握手之外,没有更多的HTTP标头解析。此外,随着成功发送越来越多的数据包,TCP拥塞窗口变大,有效地减少了RTT。


AFAIR有一个入站端口,但始终为每个连接打开一个出站端口。实际上,这只是C10k问题的一部分。
2014年

14

任何现代的单台服务器都可以一次为数千个客户端提供服务。它的HTTP服务器软件必须面向事件驱动(IOCP)(我们不再使用旧的Apache中的一个连接=一个线程/进程方程式了)。甚至Windows内置的HTTP服务器(http.sys)都是面向IOCP的,并且非常有效(以内核模式运行)。从这个角度来看,WebSockets和常规HTTP连接之间的缩放比例不会有太大区别。一个TCP / IP连接使用的资源很少(比线程少得多),并且现代OS已针对处理大量并发连接进行了优化:WebSocket和HTTP只是OSI 7应用程序层协议,继承了此TCP / IP规范。

但是,从实验中,我已经看到WebSockets的两个主要问题:

  1. 它们不支持CDN。
  2. 他们有潜在的安全问题。

因此,对于任何项目,我都会建议以下内容:

  • 仅将WebSockets用于客户端通知(具有用于长轮询的后备机制-周围有很多库);
  • 对所有其他数据使用RESTful / JSON,对CDN或代理使用缓存。

实际上,完整的WebSockets应用程序不能很好地扩展。只需将WebSocket用于其设计目的即可:将通知从服务器推送到客户端。

关于使用WebSockets的潜在问题:

1.考虑使用CDN

今天(近4年后),Web扩展涉及使用Content Delivery Network(CDN)前端,不仅用于静态内容(html,css,js),还用于您的(JSON)应用程序数据

当然,您不会将所有数据都放在CDN缓存中,但实际上,许多常见内容不会经常更改。我怀疑您的REST资源中有80%可能会被缓存...即使一分钟(或30秒)的CDN过期时间也可能足以使您的中央服务器重新启动,并大大增强了应用程序的响应能力,因为CDN可以地理位置调整...

据我所知,CDN还没有WebSockets支持,我怀疑它永远不会支持。WebSockets是有状态的,而HTTP是无状态的,因此很容易缓存。实际上,要使WebSockets CDN友好,您可能需要切换到无状态RESTful方法……这将不再是WebSockets。

2.安全问题

WebSocket具有潜在的安全问题,尤其是有关DOS攻击的安全问题。有关新的安全漏洞的说明,请参阅此幻灯片此Webkit票证

WebSocket避免了在OSI 7应用程序层级别进行数据包检查的任何机会,这在当今的任何业务安全性中已成为非常标准的做法。实际上,WebSockets使传输变得混乱,因此可能是安全漏洞的重大突破。


2
@ArnaudBouchez-为CDN上的精彩展示+1。快速跟进问题-您如何看待事件交付网络的可行性?模仿CDN,但旨在通过websocket或其他尚未见到的技术来传递流数据等。
quixver 2014年

8

这样考虑:什么便宜,为每个请求保留一个开放的连接,或打开一个新的连接(这样做的协商开销,请记住它是TCP。)

当然,这取决于应用程序,但是对于长期的实时连接(例如AJAX聊天),最好保持连接打开。

最大连接数将受套接字的最大可用端口数限制。


您可以不使用WebSocket来保持连接打开(由于使用了HTTP / 1.1的keep alive选项)。我不确定我是否理解你的意思。
2014年

1
+1。人们往往会忘记建立涉及syn / ack / ack的TCP连接,而TLS需要更多的往返时间来进行密钥交换。
quixver 2014年

1
@ArnaudBouchez检查en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1只要需要,WebSocket就会打开,并且不会变黑(例如长轮询和其他替代方法)。
kaoD

-5

不,它不能扩展,为中间路由交换器付出了巨大的努力。然后在服务器端,页面错误(必须保留所有这些描述符)达到很高的值,并且将资源带入工作区的时间增加了。这些主要是用JAVA编写的服务器,因此保留这些套接字套接字比销毁/创建一个套接字可能更快。当您在计算机上运行这样的服务器时,其他任何进程将无法移动。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.