【问题标题】:How/where to inject server communication into a Flux workflow?如何/在哪里将服务器通信注入 Flux 工作流程?
【发布时间】:2016-05-23 21:49:27
【问题描述】:

上下文

我们正在构建一个基于 Flux 的 Web 应用程序,其中客户端(Flux/React/TypeScript)通过 websockets(而不是通过 HTTP GET)与服务器 (C#) 通信。

当执行客户端操作时,我们通过 Web 套接字连接向服务器发送命令请求。

服务器总是快速响应第一个 Start 响应(指示它是否可以执行请求的操作),然后响应 1 个或多个 Progress 响应(可能是数百个响应,其中包含有关已执行操作的进度信息)。当服务器上的操作完成时,最后一个 Progress 响应将具有 100% 的进度分数和“OK”错误状态。

请注意,一些服务器操作可能只需要 100 毫秒,但其他可能需要长达 10 分钟(因此会有进度响应,因此客户端可以向用户显示有关操作的一些信息)。

在客户端,我们有:

  • 我们调用的 sendCommandRequest 函数通过 websocket 向服务器发送命令请求
  • 一个处理函数handleCommandResponse(在websocket onMessage回调中调用)

我们的问题是:将服务器通信注入基于 Flux 的应用程序的最佳方式是什么?我们应该在哪里对 websocket 进行 send 调用,我们应该如何从 websocket 的回调返回 Flux 链?

提案

假设我们更改了客户端 GUI 中的视觉效果参数(浮点数,在文本字段框中设置),这会触发服务器上生成新图像的操作。此操作需要 1 秒才能在服务器上执行。

现在,情况是这样的,GUI 处理程序将向调度程序发送一个 Flux 动作,调度程序调用向其注册的商店的回调,然后商店根据动作有效负载更新其数据,并且通过更改事件回调触发各种组件,这些回调使用 setState 和新的商店数据来触发重新渲染。

我们可以让商店在他们更改数据(如新参数值)时通过 websocket 向服务器发送命令请求。此时,存储将具有新的参数值,而图像仍然是最后接收到的图像(来自上一个命令)。

从那一刻起,服务器开始向客户端发回 Progress 响应,这些响应到达 websocket onMessage 回调,最终的 Progress 响应将包含新图像(2 秒后)。

在 websocket onMessage 回调中,我们现在可以向调度程序发送第二个 Flux 操作,将新接收到的图像作为有效负载,这将导致商店使用新图像更新其数据,这将导致监听组件重新渲染。

这个问题是:

  • Flux 存储可以有部分更新的数据:只要服务器没有发回最终结果,存储就会有新的参数,但仍然是旧图像
  • 我们现在需要 2 个 Flux 操作:一个由 GUI 用来表示用户进行了一些更改,另一个由 Web 套接字回调用来表示某些结果到达
  • 如果服务器端出现问题,新参数已经在 Flux 存储中设置,而我们将永远不会收到新图像,因此存储中的数据会损坏

在 Flux 工作流程中是否有更好的方法来适应服务器通信? 有什么建议/最佳做法吗?

【问题讨论】:

    标签: reactjs websocket client-server flux


    【解决方案1】:

    如果服务器端出现问题,新参数已经在 Flux 存储中设置,而我们永远不会收到新图像,因此存储中的数据会损坏

    以下是一些故障保护措施:

    • 缓存

    我们在每个 API 节点上都有一个缓存层。这种技术不仅可以改善延迟(最多 20%),而且可以在依赖服务出现故障时提高可用性。此外,依赖系统的负载显着减少(在我们的例子中减少了 70%)。为了获得最大的灵活性,我们将缓存放置在依赖调用附近,并在我们的实现中使用 Guava。

    • 依赖保护

    有时,我们会注意到依赖服务会降级的模式,从而导致 API 系统中的线程停止。由于线程耗尽,这会显着降低吞吐量,并可能导致系统停机。为避免这种情况,我们对依赖项实施了激进的超时,并采用了一种自动化机制来消除对依赖项服务的调用。这种技术显着提高了可伸缩性,因为线程现在可以继续而不是等待超时。

    • 推测重试

    在我们的分析中,与 p95 延迟相比,某些依赖项往往具有不成比例的大 p99(也称为 99th-percentile)延迟。更一般地,我们看到延迟急剧上升的模式。在发生延迟跳跃的地方,我们引入了并行重试,并消耗收到的第一个响应。权衡是增加我们依赖系统的流量,以换取更低的延迟和错误率。在我们的案例中,这种方法将延迟降低了高达 22%,错误率降低了高达 81%。

    • 重连算法

    XMPP 服务器可能会在 为来自连接的客户端和远程服务器的 TCP 连接提供服务。 由于此类连接的数量可能非常大,因此 寻求重新连接的实体采用的重新连接算法 会对软件性能和网络产生重大影响 拥塞。如果实体选择重新连接,它:

    SHOULD set the number of seconds that expire before reconnecting
    
      to an unpredictable number between 0 and 60 (this helps to ensure
      that not all entities attempt to reconnect at exactly the same
      number of seconds after being disconnected).
    
    SHOULD back off increasingly on the time between subsequent
    
      reconnection attempts (e.g., in accordance with "truncated binary
      exponential backoff" as described in [ETHERNET]) if the first
      reconnection attempt does not succeed.
    
    • TLS 恢复

    本规范描述了一种分发加密的机制 以票据的形式向客户端提供会话状态信息和 将票证返回给服务器的机制。车票是 由 TLS 服务器创建并发送到 TLS 客户端。 TLS 客户端 向 TLS 服务器出示票证以恢复会话。 本规范的实现预计将同时支持 机制。

    传统上,Web 应用程序和原生应用程序之间的主要区别之一是,与 Web 应用程序不同,原生应用程序可以离线运行。这种情况发生了变化——Service Workers 等技术允许网站或 Web 应用程序缓存必要的资产,这样它仍然可以在离线时运行。这包括诸如 JavaScript 文件、CSS 和图像之类的东西。将此技术与诸如 localStorage 之类的智能使用相结合,即使 Internet 连接中断,您的游戏也可以继续运行。您只需要在再次连接时同步所有更改。

    参考文献

    【讨论】:

    • 感谢您的实质性回答!我会消化一下,看看什么适用于我的用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多