我很好奇是否有人知道HTML WebSockets的可伸缩性。对于我阅读的所有内容,似乎每个客户端都将与服务器保持一条开放的通讯线路。我只是想知道它如何扩展以及服务器可以处理多少个打开的WebSocket连接。也许将这些连接保持打开状态在现实中不是问题,但感觉确实是这样。
我很好奇是否有人知道HTML WebSockets的可伸缩性。对于我阅读的所有内容,似乎每个客户端都将与服务器保持一条开放的通讯线路。我只是想知道它如何扩展以及服务器可以处理多少个打开的WebSocket连接。也许将这些连接保持打开状态在现实中不是问题,但感觉确实是这样。
Answers:
在大多数情况下,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 /长轮询模型的运行状况。转换工作并非易事,因此在许多情况下,付出的代价是不值得的。
更新:
需要澄清的是:在这种情况下,服务器可以支持的客户端连接数与端口无关,因为服务器(通常)仅在单个端口上侦听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。
任何现代的单台服务器都可以一次为数千个客户端提供服务。它的HTTP服务器软件必须面向事件驱动(IOCP)(我们不再使用旧的Apache中的一个连接=一个线程/进程方程式了)。甚至Windows内置的HTTP服务器(http.sys)都是面向IOCP的,并且非常有效(以内核模式运行)。从这个角度来看,WebSockets和常规HTTP连接之间的缩放比例不会有太大区别。一个TCP / IP连接使用的资源很少(比线程少得多),并且现代OS已针对处理大量并发连接进行了优化:WebSocket和HTTP只是OSI 7应用程序层协议,继承了此TCP / IP规范。
但是,从实验中,我已经看到WebSockets的两个主要问题:
因此,对于任何项目,我都会建议以下内容:
- 仅将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使传输变得混乱,因此可能是安全漏洞的重大突破。
这样考虑:什么便宜,为每个请求保留一个开放的连接,或打开一个新的连接(这样做的协商开销,请记住它是TCP。)
当然,这取决于应用程序,但是对于长期的实时连接(例如AJAX聊天),最好保持连接打开。
最大连接数将受套接字的最大可用端口数限制。