我写的应用程序的一部分需要从客户端向服务器传输任意大的(对于此问题,我将假设100-200 GB)的文件。重要的是,接收器(服务器)不存储这个文件 - 它只是读取/检查流并将其发送到下一个点。因为在任何时候我都需要整个文件,但是希望同时进行多次传输,所以我想尽量减少内存使用量并消除磁盘使用量。我想以1 MB大块处理文件。通过反应流发送大文件
现在,服务器使用Spring Boot和Akka。
我的第一次尝试是在客户端打开缓冲的文件输入流,以1 MB的块为单位读取它,并以单独的线程在消息中发送它们。它可以工作,但问题在于客户端一个接一个地发送消息,而不必担心服务器是否有缓冲区来存储消息(缺乏背压)。
我的第二个想法是用阿卡流是这样的:
How to use Reactive Streams for NIO binary processing?
利用ActorPublisher的是这样的:
akka-streams with akka-cluster
然而,如前所述这里:
“Warning ActorPublisher和ActorSubscriber可能会在未来版本的Akka中被弃用。
警告 ActorPublisher和ActorSubscriber不能与远程参与者使用,因为如果反应流协议(例如请求)的信号丢失的流可能死锁。”
它不像好主意。
我不想将它保存在任何存储提供程序(dropbox,谷歌驱动器,...),因为我想动态分析数据。我有弹簧5和Akka在船上,但我可以使用任何其他软件,这将解决此问题。原始插座将缺乏背压和山洪不保证顺序/有序的读写(我需要)。
主要问题是:如何将大文件从客户端传输到服务器,假设服务器无法一次将文件存储在磁盘或ram中?
奖金的问题是:如何计算在这种转移中的“正确”大块大小?
我一直在寻找答案的日子,看起来像我不是唯一一个这样的问题,但没有指出其他适当的替代解决方案没有答案或答案像“不这样做”。
目前尚不清楚您的问题到底是什么。Akka流提供了你所需要的所有工具 - TCP套接字周围有流封装(当然还有背压),并且有'GraphStage'(这是你可以用来实现处理的ActorSubscriber和ActorPublisher的预期替代品)如果没有默认的组合器适合你,则为逻辑。你只需要合并它们。 –
你会如此友善并向我展示一些远程流的最小例子吗? – spam
当然,这是:https://gist.github.com/netvl/1245564b106c02691dd0808fe98d07eb。它非常肮脏(特别是在服务器关机处理时),但它应该传达基本的想法。它使用原始的TCP套接字进行通信;你也可能想使用akka-http,因为它也给你更简单的TLS配置(尽管也可以用原始TCP流来完成)。 TCP流被记录[在这里](http://doc.akka.io/docs/akka/2.4/scala/stream/stream-io.html#streaming-tcp),并且akka-http记录在[这里](http ://doc.akka.io/docs/akka-http/current/scala.html)。 –