【问题标题】:Java streaming rest APIJava 流式休息 API
【发布时间】:2020-11-30 01:56:11
【问题描述】:

我总是对如何将响应流回客户端(例如大型 csv 文件)感到困惑,我想问一些问题:

  1. 我正在逐行读取文件并使用flush() 一点一点地直接写入输出流,这是否足够或者它仍然取决于特定操作系统上的flush() 实现?
  2. 假设我有一台非常强大的机器,最后只刷新,客户端是否还能以流的方式处理答案(不将所有内容加载到内存中)?
  3. 客户端提到响应可能没有分块,是关于Chunked_transfer_encoding,那么这对响应有什么影响呢?顺便说一句,当我发回文件时,我已经知道响应大小。
  4. 客户还谈到了StreamingResponseBody。我的理解是这仅用于异步处理,我们可以在不使用它的情况下将数据流回。
  5. 最后一个问题,反应式编程与此有关吗?我的用户案例非常简单,不涉及并发请求。我知道所有语言都有很多现代框架,但我更愿意先了解基本知识。

抱歉所有问题。

【问题讨论】:

    标签: java streaming reactive-programming


    【解决方案1】:
    1. 您使用 Java flush(),它在每个 O/S 上的行为相同,即使 O/S 刷新可能不同。
    2. 客户端只看到一个不依赖于它是如何生成的数据流。

    ...

    1. 反应式编程与此没有共同之处。它用于最大程度地减少大量连接的内存消耗。如果您的客户端少于 1000 个,请使用普通同步多线程。更容易编码和调试。

    【讨论】:

    • 感谢您的回答,这基本上是我的想法。关于flush()方法,我的意思是当我们在java中刷新时,是否保证操作系统会进行刷新,因为如果不是,那么实际上仍然有可能将数据刷新一次到客户端。
    • 有关刷新行为的详细信息,请阅读文档docs.oracle.com/javase/7/docs/api/java/io/…
    【解决方案2】:

    StreamingResponseBody 是 Spring Boot 框架的一部分。如果您的客户特别提到它,可能是因为他们更熟悉 Spring Boot 客户端,因为它为处理流管理等复杂处理提供了标准抽象。此外,即使您的服务器足够强大,可以将整个大文件内容加载到内存中——在单个块中发送回如此大的数据可能存在网络限制——它也可能导致客户端出错。所以建议使用流式传输机制

    【讨论】:

      【解决方案3】:

      这实际上并不是您在实践中对大文件所做的。您通常会做的是,当您收到生成某些文件的请求 foo.txt 时,您可以立即使用 url 回复:https://foobar.com/foowillbehere/foo.txt,(或者您可以保持连接,但这不是长期过程的好习惯)。

      在后端,您将写入一个位置,该位置是 url https://foobar.com/foowillbehere/foo.txt 为客户端解析的位置。这可以是文件服务器/网络存储。

      现在,如果他们再次请求该文件,则您已准备好提供该文件。如果在特定步骤中出现问题,您可以简单地重试,并且客户端不知道他们是否仍然可以从您提供给他们的url 下载文件等。否则您的用户体验会很差如果连接出现任何问题,他们将需要再次请求此大文件,而且您也无法随时提供该文件。您可以发现的另一件事通常是,如果您将 HTTP 连接和处理捆绑在一起,如果同时上传太多文件,您的应用程序可能会崩溃。我们在将应用程序的上传移至 s3 之前发现了这一点,然后将执行文件处理的服务器与响应 REST 请求的服务器分开。

      【讨论】:

      • 感谢您的回答,但这不是我要问的。当用户请求文件时,文件就准备好了(用户发送一个将生成文件的帖子,但这需要时间,所以我们异步执行,然后用户发送一个 get 来下载文件)。
      猜你喜欢
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 2020-02-15
      • 2018-06-14
      • 2020-07-13
      • 2014-11-09
      • 2014-10-23
      • 1970-01-01
      相关资源
      最近更新 更多