缓冲 REST 响应的方法

2022-09-04 21:35:04

有一个 REST 终结点,它为我的应用程序提供大量(数十 GB)数据块。
应用程序按照自己的节奏处理数据,随着传入数据量的增长,我开始遇到 REST 终结点超时。
这意味着,处理速度低于网络整体。
不幸的是,没有办法提高足够的处理速度,因为没有“足够” - 传入的数据量可能会无限增长。

我正在考虑一种在处理之前将传入数据存储在本地的方法,以便在超时发生之前释放REST端点连接。

到目前为止,我得出的结论是将传入的数据下载到临时文件,并使用输出流/输入流同时读取(处理)所述文件。
使用文件进行缓冲的排序。

这带来了它自己的问题:

  • 如果处理速度变得比下载速度快一段时间,我得到EOF怎么办?
  • 文件解析器使用ObjectInputStream运行,在空文件/ EOF的情况下,它的行为很奇怪
  • 等等

有没有传统的方法来做这样的事情?
是否有替代解决方案?
请提供一些指导。

Upd:

我想指出:http服务器超出了我的控制范围。
将其视为供应商数据提供程序。他们有很多消费者,拒绝只改变一个消费者。
看起来我们是唯一使用其所有数据的人,因为我们的客户应用程序处理速度远远大于他们的示例客户端性能指标。尽管如此,我们仍然无法将应用程序性能与网络整体匹配。

服务器不支持 http 范围请求或分页。
无法将数据划分为要加载的块,因为没有筛选属性来保证每个块都足够小。

很快:我们可以在超时发生之前下载给定时间内的所有数据,但无法处理它。
在输入流和外流之间有一个适配器,将pefrorm作为阻塞队列,将会很有帮助。


答案 1

您正在使用类似的东西,EOF的解决方案可能是将第一个包裹在一个中,只要作者正在编写,在击中EOF时就会阻止。new ObjectInputStream(new FileInputStream(..._)FileInputStreamWriterAwareStream

无论如何,如果延迟无关紧要,我不会在下载完成之前开始处理。通常,对于不完整的对象列表,您无能为力。

也许一些基于内存映射文件的队列(如Chronicle-Queue)可能会对您有所帮助。它比直接处理文件更快,并且可能更易于使用。


您还可以使用队列在内部实现一个队列,该队列从其输入流中读取,并且,如果它有大量数据,它会将它们吐出到磁盘。这可能是一个不错的抽象,完全隐藏了缓冲。HugeBufferingInputStream

在番石榴中也有,当变大时,它会自动从使用内存切换到使用文件,但恐怕它是针对小尺寸(预期数十千兆字节,没有尝试使用内存的意义)。FileBackedOutputStream


答案 2

是否有替代解决方案?

如果您的使用者(http 客户端)在跟上数据流方面遇到困难,您可能希望查看客户端管理其自己的正在进行的工作,按需从服务器提取数据的设计。

RFC 7233 描述了范围请求

具有有限本地存储的设备可能受益于只能请求较大表示的子集,例如非常大的文档的单页或嵌入图像的尺寸

MDN Web Docs站点上的HTTP Range请求可能是一个更平易近人的介绍。


推荐