我寫的應用程序的一部分需要從客戶端向服務器傳輸任意大的(對於此問題,我將假設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)。 –