HTML WebSockets是否为每个客户维护一个开放的连接? 这是否规模?

我很好奇,如果有人有关于HTML WebSockets的可伸缩性的任何信息。 对于我读过的所有内容,似乎每个客户端都将保持与服务器的开放式沟通。 我只是想知道如何扩展和一个服务器可以处理多less打开的WebSocket连接。 也许把这些连接打开并不是现实中的问题,但感觉就是这样。

在大多数情况下,WebSockets可能比AJAX / HTML请求的规模更好。 但是,这并不意味着WebSockets是所有AJAX / HTML使用的替代品。

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

曾经尝试过configuration一个Web服务器来支持数以万计的同时AJAX客户端? 将这些客户端改为WebSockets客户端,这可能是可行的。

尽pipeHTTP连接长时间不创build打开文件或消耗端口号,但几乎每隔一段时间都会更昂贵:

  • 每个HTTP连接都带有很多大部分时间不使用的行李:Cookie,内容types,内容长度,用户代理,服务器ID,date,最后修改等等。一旦WebSockets连接build立,只有应用程序所需的数据需要来回发送。

  • 通常,HTTP服务器被configuration为logging占用磁盘和CPU时间的每个HTTP请求的开始和完成。 loggingWebSockets数据的启动和完成将成为标准,但是在进行双工传输的WebSockets连接时,不会有任何额外的日志开销(除非应用程序/服务被devise为这样做)。

  • 通常,使用AJAX的交互式应用程序不断轮询或使用某种长轮询机制。 WebSockets是一个更简洁的(和更低的资源)的方式来做更多的事件模型,当服务器和客户端通过对现有的连接进行报告时,通知对方。

  • 生产中大多数stream行的Web服务器都有一个用于处理HTTP请求的进程(或线程)池。 随着压力的增加,池的大小将会增加,因为每个进程/线程一次处理一个HTTP请求。 每个额外的进程/线程使用更多的内存,创build新的进程/线程比创build新的套接字连接(这些进程/线程仍然需要)要昂贵得多。 大多数stream行的WebSocket服务器框架正在进行事件性的路线,这往往会扩大和performance更好。

WebSockets的主要优点是交互式Web应用程序的低延迟连接。 它比HTTP AJAX /长轮询(假设应用程序/服务器devise正确)能够更好地扩展和消耗更less的服务器资源,但是IMO低延迟是WebSocket的主要优势,因为它将启用不可能的新类Web应用程序与目前AJAX /长时间轮询的开销和延迟。

一旦WebSockets标准变得更加完善并且有了更广泛的支持,那么将它用于大多数需要频繁与服务器通信的新型交互式Web应用程序将是有意义的。 对于现有的交互式Web应用程序,它将真正取决于当前的AJAX /长轮询模型是如何工作的。 转换的努力将是不平凡的,因此在许多情况下,成本只是不值得的。

更新

有用的链接: AWS上使用Node.js的600k个并发websocket连接

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

至于通过WS和HTTP减less延迟,这是真的,因为除了初始的WS握手之外,没有更多的HTTP头parsing。 另外,随着越来越多的数据包被成功发送,TCP拥塞窗口变宽,有效地减less了RTT。

任何现代化的单一服务器都能够同时服务数千个客户端 。 它的HTTP服务器软件只是面向事件驱动(IOCP)(我们不再是旧的Apache一个连接=一个线程/进程方程)。 即使在Windows(http.sys)中构build的HTTP服务器也是面向IOCP的,并且非常高效(在内核模式下运行)。 从这个angular度来看,在WebSockets和普通的HTTP连接之间进行扩展将不会有太大的区别。 一个TCP / IP连接使用一个小资源(比一个线程less得多),现代操作系统为处理大量的并发连接而优化:WebSockets和HTTP只是OSI 7应用层协议,inheritance了这个TCP / IP规范。

但是,从实验中,我看到了WebSocket的两个主要问题:

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

所以我会为任何项目推荐以下内容:

  • 只使用WebSockets进行客户端通知(使用回退机制来进行长轮询 – 周围有大量的库);
  • 对所有其他数据使用RESTful / JSON,使用CDN或代理caching。

实际上,完整的WebSockets应用程序不能很好地扩展。 只需使用WebSocket来实现它们的目的:将通知从服务器推送到客户端。

关于使用WebSocket的潜在问题:

1.考虑使用CDN

今天(接近4年后),networking扩展涉及使用内容交付networking (CDN)前端,不仅用于静态内容(html,css,js),还包括您的(JSON)应用程序数据 。

当然,你不会把所有的数据放在你的CDNcaching中,但实际上很多常见的内容不会经常改变。 我怀疑有80%的REST资源可能被caching…即使是一分钟 (或30秒)的CDN过期超时也许足以让您的中央服务器有一个新的活动,并且提高了应用程序的响应能力,因为CDN可以经过地理调整

据我所知,CDN还没有WebSocket的支持,我怀疑它永远不会。 WebSockets是有状态的,而HTTP是无状态的,所以很容易被caching。 事实上,为了使WebSocket对CDN友好,您可能需要切换到无状态的REST风格的方法,这将不再是WebSockets。

2.安全问题

WebSocket有潜在的安全问题,尤其是DOS攻击。 有关新的安全漏洞的说明,请参阅这组幻灯片和此webkit票据 。

WebSockets在OSI 7应用层级上避免了任何数据包检测的可能性,在任何业务安全性方面,它现在都是相当标准的。 事实上,WebSocket使得传输混淆,因此可能是安全漏洞的重大破坏。

这样想:什么更便宜,保持开放的连接,或为每个请求打开一个新的连接(谈判开销这样做,记住它是TCP。)

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

连接的最大数量将受到sockets的最大空闲端口数的限制。

我觉得所有这些协议层都是由于缺乏基础知识而发明的。 如何稳定的连接和汇集数百万的描述符可以更好地扩展,然后让服务离开我对此表示怀疑。 这些人是否曾经用C写过一个TCP简单的服务器来看看更好的尺度? 我不这么认为。