HTMLWebSockets 是否为每个客户端维护一个开放连接? 是否扩展?

我很好奇是否有人知道关于 HTML WebSocket 可伸缩性的任何信息。从我读到的所有内容来看,似乎每个客户端都会与服务器保持一条开放的通信线路。我只是想知道它是如何扩展的,以及一个服务器可以处理多少个打开的 WebSocket 连接。也许在现实中保持这些连接开放不是问题,但感觉就是问题。

45982 次浏览

可以这样想: 保持一个开放的连接,或者为每个请求打开一个新的连接(这样做的协商开销,请记住它是 TCP) ,这样做的成本更低

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

最大连接数将以套接字的最大可用端口数为上限。

在大多数方面,WebSocket 可能比 AJAX/HTML 请求扩展得更好。然而,这并不意味着 WebSocket 可以替代 AJAX/HTML 的所有用途。

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

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

HTTP 连接虽然在很长一段时间内不会创建打开的文件或使用端口号,但几乎在所有其他方面都更加昂贵:

  • 每个 HTTP 连接都承载着许多大多数时候不会使用的包袱: cookies、内容类型、内容长度、用户代理、服务器 ID、日期、最后修改等等。一旦建立了 WebSockets 连接,只有应用程序需要的数据需要来回发送。

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

  • 通常,使用 AJAX 的交互式应用程序要么连续轮询,要么使用某种长轮询机制。WebSockets 是一种更简洁(且资源更少)的事件模型方法,服务器和客户机在现有连接上有需要报告的内容时会相互通知。

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

WebSocket 的主要好处是交互式 Web 应用程序的延迟连接更低。它将比 HTTP AJAX/long-poll (假设应用程序/服务器设计得当)更好地扩展和消耗更少的服务器资源,但 IMO 更低的延迟是 WebSocket 的主要好处,因为它将启用新类别的 Web 应用程序,这些应用程序在目前 AJAX/long-poll 的开销和延迟下是不可能的。

一旦 WebSocket 标准变得更加完善并获得更广泛的支持,将其用于需要经常与服务器通信的大多数新的交互式 Web 应用程序将是有意义的。对于现有的交互式 Web 应用程序,它将真正取决于当前 AJAX/long-poll 模型的工作效果。转换的努力将是不平凡的,因此在许多情况下,成本就是不值得的好处。

更新 :

有用链接: 使用 Node.js 的 AWS 上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 减少延迟,这是正确的,因为除了最初的 WS 握手之外没有更多的 HTTP 头解析。另外,随着越来越多的数据包被成功地发送,TCP 拥塞窗口变宽,有效地减少了 RTT。

任何现代的单一服务器都能够服务 成千上万的客户。它的 HTTP 服务器软件必须是面向事件驱动(IOCP)的(我们不再是旧的 Apache 一个连接 = 一个线程/进程等式)。即使是 Windows 内置的 HTTP 服务器(HTTP.sys)也是面向 IOCP 的,并且非常高效(以内核模式运行)。从这个角度来看,WebSocket 和普通 HTTP 连接在伸缩方面没有太大区别。一个 TCP/IP 连接使用很少的资源(比一个线程少得多) ,现代操作系统为处理大量并发连接进行了优化: WebSocket 和 HTTP 只是 OSI 7应用层协议,继承了 TCP/IP 规范。

但是,通过实验,我发现 WebSocket 存在两个主要问题:

  1. 它们不支持 CDN;
  2. 他们有潜在的安全隐患。

因此,对于任何项目,我建议如下:

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

实际上,完整的 WebSocket 应用程序不能很好地伸缩。只要使用 WebSocket 就可以了: 将通知从服务器推送到客户端。

关于使用 WebSocket 的潜在问题:

1. 考虑使用 CDN

今天(将近4年之后) ,Web 缩放涉及到使用 内容传递网路(CDN)前端,不仅用于静态内容(html、 css、 js) ,还用于 您的(JSON)应用程序数据

当然,您不会将所有数据放在 CDN 缓存中,但是在实践中,许多常见的内容不会经常更改。我怀疑80% 的 REST 资源可能被缓存... 甚至一个 等一下(或30秒) CDN 过期超时可能足以给您的中央服务器一个新的活动,并大大提高应用程序的响应能力,因为 CDN 可以进行地理调优..。

据我所知,目前 CDN 中还没有对 WebSocket 的支持,而且我怀疑永远也不会有。WebSocket 是有状态的,而 HTTP 是无状态的,因此很容易缓存。事实上,为了使 WebSockets 对 CDN 友好,您可能需要切换到无状态 RESTful 方法... ... 这将不再是 WebSockets。

2. 安全问题

WebSocket 有潜在的安全问题,特别是关于 DOS 攻击。

WebSockets 避免了在 OSI 7应用程序层级进行数据包检查的任何机会,这在当今任何业务安全领域都已成为相当标准的做法。事实上,WebSocket 使传输变得模糊,因此可能是一个重大的安全漏洞。

不,它没有规模,给中间路线交换机巨大的工作。然后在服务器端,页面错误(您必须保留所有这些描述符)达到了很高的值,将资源带入工作区域的时间增加了。这些大多是 JAVA 编写的服务器,保留这些大量的套接字然后销毁/创建一个套接字可能会更快。 当您在一台机器上运行这样的服务器时,任何其他进程都不能再移动。