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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4852702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 06:25:47  来源:igfitidea点击:

Do HTML WebSockets maintain an open connection for each client? Does this scale?

htmlwebsocket

提问by Ryan Montgomery

I am curious if anyone has any information about the scalability of HTML WebSockets. For everything I've read it appears that every client will maintain an open line of communication with the server. I'm just wondering how that scales and how many open WebSocket connections a server can handle. Maybe leaving those connections open isn't a problem in reality, but it feels like it is.

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

回答by kanaka

In most ways WebSockets will probably scale better than AJAX/HTML requests. However, that doesn't mean WebSockets is a replacement for all uses of AJAX/HTML.

在大多数情况下,WebSockets 可能会比 AJAX/HTML 请求更好地扩展。然而,这并不意味着 WebSockets 是 AJAX/HTML 的所有用途的替代品。

Each TCP connection in itself consumes very little in terms server resources. Often setting up the connection can be expensive but maintaining an idle connection it is almost free. The first limitation that is usually encountered is the maximum number of file descriptors (sockets consume file descriptors) that can be open simultaneously. This often defaults to 1024 but can easily be configured higher.

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

Ever tried configuring a web server to support tens of thousands of simultaneous AJAX clients? Change those clients into WebSockets clients and it just might be feasible.

曾经尝试过配置 Web 服务器以支持数万个并发 AJAX 客户端吗?将这些客户端更改为 WebSockets 客户端,这可能是可行的。

HTTP connections, while they don't create open files or consume port numbers for a long period, are more expensive in just about every other way:

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

  • Each HTTP connection carries a lot of baggage that isn't used most of the time: cookies, content type, conetent length, user-agent, server id, date, last-modified, etc. Once a WebSockets connection is established, only the data required by the application needs to be sent back and forth.

  • Typically, HTTP servers are configured to log the start and completion of every HTTP request taking up disk and CPU time. It will become standard to log the start and completion of WebSockets data, but while the WebSockets connection doing duplex transfer there won't be any additional logging overhead (except by the application/service if it is designed to do so).

  • Typically, interactive applications that use AJAX either continuously poll or use some sort of long-poll mechanism. WebSockets is a much cleaner (and lower resource) way of doing a more event'd model where the server and client notify each other when they have something to report over the existing connection.

  • Most of the popular web servers in production have a pool of processes (or threads) for handling HTTP requests. As pressure increases the size of the pool will be increased because each process/thread handles one HTTP request at a time. Each additional process/thread uses more memory and creating new processes/threads is quite a bit more expensive than creating new socket connections (which those process/threads still have to do). Most of the popular WebSockets server frameworks are going the event'd route which tends to scale and perform better.

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

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

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

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

The primary benefit of WebSockets will be lower latency connections for interactive web applications. It will scale better and consume less server resources than HTTP AJAX/long-poll (assuming the application/server is designed properly), but IMO lower latency is the primary benefit of WebSockets because it will enable new classes of web applications that are not possible with the current overhead and latency of AJAX/long-poll.

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

Once the WebSockets standard becomes more finalized and has broader support, it will make sense to use it for most new interactive web applications that need to communicate frequently with the server. For existing interactive web applications it will really depend on how well the current AJAX/long-poll model is working. The effort to convert will be non-trivial so in many cases the cost just won't be worth the benefit.

一旦 WebSockets 标准更加最终确定并获得更广泛的支持,就可以将其用于大多数需要与服务器频繁通信的新交互式 Web 应用程序。对于现有的交互式 Web 应用程序,它实际上取决于当前 AJAX/长轮询模型的工作情况。转换的努力将是非常重要的,因此在许多情况下,成本不值得收益。

Update:

更新

Useful link: 600k concurrent websocket connections on AWS using Node.js

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

回答by Michael

Just a clarification: the number of client connections that a server can support has nothing to do with ports in this scenario, since the server is [typically] only listening for WS/WSS connections on one single port. I think what the other commenters meant to refer to were file descriptors. You can set the maximum number of file descriptors quite high, but then you have to watch out for socket buffer sizes adding up for each open TCP/IP socket. Here's some additional info: https://serverfault.com/questions/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

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

As for decreased latency via WS vs. HTTP, it's true since there's no more parsing of HTTP headers beyond the initial WS handshake. Plus, as more and more packets are successfully sent, the TCP congestion window widens, effectively reducing the RTT.

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

回答by Arnaud Bouchez

Any modern single server is able to server thousands of clients at once. Its HTTP server software has just to be is Event-Driven (IOCP) oriented (we are not in the old Apache one connection = one thread/process equation any more). Even the HTTP server built in Windows (http.sys) is IOCP oriented and very efficient (running in kernel mode). From this point of view, there won't be a lot of difference at scaling between WebSockets and regular HTTP connection. One TCP/IP connection uses a little resource (much less than a thread), and modern OS are optimized for handling a lot of concurrent connections: WebSockets and HTTP are just OSI 7 application layer protocols, inheriting from this TCP/IP specifications.

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

But, from experiment, I've seen two main problems with WebSockets:

但是,从实验中,我发现 WebSockets 有两个主要问题:

  1. They do not support CDN;
  2. They have potential security issues.
  1. 他们不支持 CDN;
  2. 他们有潜在的安全问题。

So I would recommend the following, for any project:

  • Use WebSockets for client notifications only (with a fallback mechanism to long-polling - there are plenty of libraries around);
  • Use RESTful / JSON for all other data, using a CDN or proxies for cache.

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

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

In practice, full WebSockets applications do not scale well. Just use WebSockets for what they were designed to: push notifications from the server to the client.

在实践中,完整的 WebSockets 应用程序不能很好地扩展。只需将 WebSockets 用于它们的设计目的:将通知从服务器推送到客户端。

About the potential problems of using WebSockets:

关于使用WebSockets的潜在问题:

1. Consider using a CDN

1. 考虑使用 CDN

Today (almost 4 years later), web scaling involves using Content Delivery Network(CDN) front ends, not only for static content (html,css,js) but also your (JSON) application data.

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

Of course, you won't put all your data on your CDN cache, but in practice, a lot of common content won't change often. I suspect that 80% of your REST resources may be cached... Even a one minute(or 30 seconds) CDN expiration timeout may be enough to give your central server a new live, and enhance the application responsiveness a lot, since CDN can be geographically tuned...

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

To my knowledge, there is no WebSockets support in CDN yet, and I suspect it would never be. WebSockets are statefull, whereas HTTP is stateless, so is much easily cached. In fact, to make WebSockets CDN-friendly, you may need to switch to a stateless RESTful approach... which would not be WebSockets any more.

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

2. Security issues

2. 安全问题

WebSockets have potential security issues, especially about DOS attacks. For illustration about new security vulnerabilities , see this set of slidesand this webkit ticket.

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

WebSockets avoid any chance of packet inspection at OSI 7 application layer level, which comes to be pretty standard nowadays, in any business security. In fact, WebSockets makes the transmission obfuscated, so may be a major breach of security leak.

WebSockets 避免了在 OSI 7 应用层级别进行数据包检查的任何机会,这在当今的任何业务安全中都是非常标准的。事实上,WebSockets 使传输变得模糊,因此可能是一个重大的安全漏洞。

回答by kaoD

Think of it this way: what is cheaper, keeping an open connection, or opening a new connection for every request (with the negotiation overhead of doing so, remember it's TCP.)

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

Of course it depends on the application, but for long-term realtime connections (e.g. an AJAX chat) it's far better to keep the connection open.

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

The max number of connections will be capped by the max number of free ports for the sockets.

最大连接数将受限于套接字的最大空闲端口数。

回答by user2195463

No it does not scale, gives tremendous work to intermediate routes switches. Then on the server side the page faults (you have to keep all those descriptors) are reaching high values, and the time to bring a resource into the work area increases. These are mostly JAVA written servers and it might be faster to hold on those gazilions of sockets then to destroy/create one. When you run such a server on a machine any other process can't move anymore.

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