使用 Websockets 代替 RESTful HTTP 的陷阱是什么?

What are the pitfalls of using Websockets in place of RESTful HTTP?

我目前正在做一个项目,需要客户端请求一个大作业并将其发送到服务器。然后服务器划分作业并响应一组 url 以供客户端进行 GET 调用并流回数据。我是项目的新手,目前正在使用 Spring websockets 来提高效率。而不是客户端不断地 ping 服务器以查看它是否有准备好流回的结果,websocket 现在将直接联系客户端万岁!

让 websockets 从头到尾管理整个过程是不是一个坏主意?我将 STOMP 与 Spring websockets 一起使用,放弃 REST 还会有重大问题吗?

这真的取决于您的要求。与 Websockets 相比,REST 服务更加透明且更容易被开发人员采用。

使用 Websockets,您消除了 RESTful 网络服务提供的大部分优势,例如通过 URI 引用资源的能力。你真正应该做的是弄清楚 REST 和超媒体的优势是什么,并据此决定这些优势对你是否重要。

当然完全有可能创建一个 RESTful 网络服务,并使用基于 websocket 的 API 来增强它以进行实时响应。

但是如果您正在创建一个只有您在受控环境中使用的服务,唯一的缺点可能是并非每个客户端都支持 websockets,而几乎任何类型的环境都可以进行简单的 http 调用。

使用 RESTful HTTP,您有一个 无状态 request/response 系统,其中客户端发送请求,服务器 returns 响应。

使用 webSockets,你有一个 有状态(或可能有状态)的消息传递系统,消息可以以任何一种方式发送,并且发送消息的开销比 RESTful HTTP request/response.

两者是完全不同的结构,具有不同的强度。

连接的 webSocket 的主要优点是:

  1. 双向通信。因此,服务器可以随时通知客户端任何事情。因此,客户端可以建立一个 webSocket 并只监听来自服务器的任何消息,而不是定期轮询服务器以查看是否有新内容。从服务器的角度来看,当客户端感兴趣的事件发生时,服务器只是向客户端发送一条消息。服务器无法使用纯 HTTP 执行此操作。

  2. 每条消息的开销较低。 如果您预计客户端和服务器之间有大量流量流动,那么使用 webSocket 的每条消息的开销较低。这是因为 TCP 连接已经建立,您只需在已经打开的套接字上发送消息即可。对于 HTTP REST 请求,您必须首先建立一个 TCP 连接,该连接在客户端和服务器之间来回多次。然后,您发送 HTTP 请求,接收响应并关闭 TCP 连接。 HTTP 请求必然会包含一些开销,例如与该服务器对齐的所有 cookie,即使这些 cookie 与特定请求无关。 HTTP/2(最新的 HTTP 规范)如果同时被客户端和服务器使用,则可以在这方面提高一些效率,因为单个 TCP 连接可以用于多个 request/response。如果您绘制了 TCP 级别的所有 requests/responses 只是为了制作 https REST request/response,与仅通过已建立的 webSocket 发送消息相比,您会感到惊讶。

  3. 在某些情况下具有更高的规模。每条消息的开销较低,并且没有客户端轮询来确定是否有新内容,这可以增加可扩展性(给定服务器可以服务的客户端数量更多)。 webSocket 可扩展性也有缺点(见下文)。

  4. 有状态连接。无需借助 cookie 和会话 ID,您可以直接在程序中存储给定连接的状态。虽然通过无状态连接进行了大量开发以解决大多数问题,但有时使用有状态连接会更简单。

RESTful HTTP request/response 的主要优点是:

  1. 普遍支持。很难得到比 HTTP 更普遍的支持。虽然现在 webSockets 得到了相对较好的支持,但在某些情况下,webSocket 支持仍然无法正常使用。

  2. 兼容更多服务器环境。有些服务器环境不允许运行长服务器进程(一些共享主机情况)。这些环境可以支持 HTTP 请求,但不支持长 运行 webSocket 连接。

  3. 在某些情况下更高的规模。持续连接的 TCP 套接字的 webSocket 要求为服务器基础设施增加了一些新的规模要求,而 HTTP 请求没有要求。所以,这最终是一个权衡 space。如果 webSockets 的优势不是真正需要或没有以重要的方式使用,那么 HTTP 请求实际上可能会更好地扩展。这绝对取决于具体的使用情况。

  4. 对于一次性request/response,单个HTTP请求比建立一个webSocket,使用它然后关闭它更有效。这是因为打开一个webSocket是从一个HTTPrequest/response开始,然后在双方同意升级到webSocket连接后,才可以发送真正的webSocket消息。

  5. 无状态。 如果你的工作没有因为无状态的基础设施而变得更复杂,那么无状态的世界可以使扩展或故障转移更容易(只需在负载均衡器后面添加或删除服务器进程。

  6. 可自动缓存。 通过正确的服务器设置,http 响应可以由浏览器或代理缓存。对于通过 webSockets 发送的请求,没有这种内置机制。


所以,为了解决您提出问题的方式:

What are the pitfalls of using websockets in place of RESTful HTTP?

  1. 大规模(数十万个客户端),您可能需要做一些特殊的服务器工作才能支持大量同时连接的 webSockets。

  2. 所有可能的客户端或工具集都不支持 webSockets 或通过它们发出的请求达到它们支持 HTTP 请求的相同级别。

  3. 一些较便宜的服务器环境不支持支持 webSockets 所需的长 运行 服务器进程。

如果将进度通知返回给客户端对您的应用程序很重要,您可以使用长 运行 http 连接并继续发送进度,也可以使用 webSocket。 webSocket 可能更容易。如果你真的只需要在这个特定的 activity 的相对较短的持续时间内使用 webSocket,那么你可能会发现最好的整体权衡集来自仅在需要推送数据的能力的持续时间内使用 webSocket到客户端,然后使用 http 请求进行正常的 request/response 活动。