【问题标题】:OutputStream to chunked responseOutputStream 到分块响应
【发布时间】:2017-05-05 17:09:16
【问题描述】:

在 Play 2.5 应用程序中,我需要创建一个服务,该服务在一个事务中从数据库中读取大量数据,并将其作为 HTTP 响应发送给客户端。

我不想使用背压,因为网速慢会导致用于从数据库获取数据的 DB 连接使用时间过长。

我当前的实现首先将数据提取到临时缓冲区(内存或文件,如果数据过多),释放 DB 连接并返回带有数据的 Ok 响应。

这样做的缺点是,当数据完全从数据库中提取出来时,首先开始向客户端发送数据。

我认为最好将数据提取到某种来源,如果超过 10kB,它将所有数据缓冲到内存和磁盘,但它会立即将数据提供给分块响应。

我打算实现这个,但我担心我不会做对并实现一些关于多线程、阻塞等的细微错误。

在此先感谢您提供任何提示、指南、现有的开放实现...

【问题讨论】:

    标签: playframework akka-stream chunked-encoding


    【解决方案1】:

    如果您使用文件作为中间缓冲区,那么它可以用作“缓冲所有数据的源”。文件可以同时写入和读取(这在 *nix 系统中肯定是正确的,对于 windows 不确定)。因此,您可以使用数据库数据写入文件并使用文件数据响应客户端。

    当收到请求时,您将启动数据库查询并将append mode 中的输出定向到缓冲区文件。

    当写入发生时,您同时将 http 响应发送回客户端,而实体由文件以读取模式提供。

    无需担心“关于多线程、阻塞等的细微错误”。因为您让操作系统和文件系统为您完成大部分工作。

    【讨论】:

    • 谢谢。我会尝试这种方法。虽然它仍然不理想。如果只有少量数据,我想将所有内容都保存在内存中。另一个问题是,如果生产者比消费者慢并且在生产者设法写入所有数据之前到达文件的当前末尾会发生什么?
    • @GregorRaýman 欢迎您。关于“如果只有少量数据”,这与原始问题“我需要创建一个读取大量数据的服务”相矛盾。如果生产比消费者慢,那很好,因为文件读取器将继续运行,直到达到 EOF(这就是所有文件读取器在最低级别都有 io 流的原因)。
    • 谢谢拉蒙,我会试试这个方法。我遇到的问题是我不知道是否会有少量数据(几 kB)或大量数据(几十 MB)。这就是为什么目前我开始在内存中缓冲数据并切换到文件,当它溢出配置的阈值时。这并不理想,因为存在延迟,并且如果消费者足够快,即使有大量数据,也可以完全避免文件。
    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多