Java HttpClient-从一个输入流写入多个POST请求

Java HttpClient-从一个输入流写入多个POST请求,java,http,tomcat,apache-httpclient-4.x,Java,Http,Tomcat,Apache Httpclient 4.x,我有一个服务器集群(可能彼此远程),它们都运行Tomcat,并使用ApacheHttpClient通过HTTP进行通信。这些服务器中有很多是数据存储,其中一个服务器是面向前端的Web服务器,充当客户机和存储之间的中介。用户应该能够将文件上载到Web服务器,Web服务器会将该文件传递到给定数量的存储区 因此,问题是:是否可以将从客户端上传的文件部分作为InputStream并同时向存储写入多个POST请求?如果我只是写本地文件,那么显而易见的解决方案就是将InputStream中的块读入byte数

我有一个服务器集群(可能彼此远程),它们都运行
Tomcat
,并使用Apache
HttpClient
通过HTTP进行通信。这些服务器中有很多是数据存储,其中一个服务器是面向前端的Web服务器,充当客户机和存储之间的中介。用户应该能够将文件上载到Web服务器,Web服务器会将该文件传递到给定数量的存储区

因此,问题是:是否可以将从客户端上传的文件部分作为
InputStream
并同时向存储写入多个
POST
请求?如果我只是写本地文件,那么显而易见的解决方案就是将
InputStream
中的块读入
byte
数组缓冲区,然后依次从缓冲区写入每个输出,但我不知道如何说服HttpClient“共享”这样的流


是的,我可以简单地将整个
InputStream
读入Web服务器上的一个对象,然后按顺序将其写入每个存储,但由于我可能会接受非常大的文件,因此我必须将数据写入磁盘,然后为每个存储服务器读回数据,而且磁盘操作的数量可能很快变得令人望而却步。这是我希望避免的实现。

创建自己的输出流。将尽可能多的HTTP POST客户端附加到此流。如果您收到输出流的日期,请将其发送到每个连接的POST客户端。

如果商店没有足够的网络带宽,它将如何“共享”流

您可以拆分传入文件并将其传递到存储,而无需将其写入磁盘,但如果只有一个存储无法跟上,则必须将该文件数据保留在内存中,直到它能够接受它。如果它是一个大文件,或者有很多用户,它可能会占用你所有的内存

更严格地说,我的意思是,您可以创建5个线程,以尽可能快的速度将数据发送到存储区,并将文件数据保存在共享的FIFO结构中。当最后一个线程访问了某个部分并发送了该部分时,可以从数据结构中删除该数据,但之前不能。如果速度慢,数据结构可能会变得巨大

数据必须在某个地方,如果不是内存和硬盘,那么在哪里

因此,将传入的数据保留在内存中,直到(如果?)内存耗尽(从不?),然后将其刷新到硬盘。通过将数据发送到存储区,然后删除,不断尝试用数据清空数据结构

您可以很容易地编写ExecutorService代码来处理数据的重新传输和清理数据结构,但它无法神奇地解决问题。:)

我没有提供源代码,因为您似乎不想要这个解决方案。如果您接受无法神奇地传递数据而不需要将数据缓冲到硬盘上,那么您可能需要帮助以后实现它(或者更糟糕的解决方案是将用户上传的数据传送到MinimumBandwidth(store1、store2、store3、store4、store5))

编辑/更改:


即使我这么说了,我也不确定你是否真的想要服务。我会创建自己的自定义线程来处理这个问题。我将从并发包创建一个集合,可能是一个LinkedBlockingQueue,它保存字节数组(不是字节,字节数组)。然后,我将从Thread->Integer创建一个映射,该映射保存传递数据时每个线程进程的当前索引。当所有进度数都高于10(表示所有线程都发送了前10个块)时,我移除前10个字节的数组,然后从所有线程的进度中减去10来重置它。

谢谢,我甚至没有考虑带宽变化的问题。我想我想要避免的解决方案就是解决方案。对不起,如果我听起来像个傻瓜,我对网络编程是个新手,我只是随便写这篇文章。我应该看看
ExecutorService
上有什么像样的文献吗?我编辑了我的答案,想给你一个评论。注释区域太短。我使用了
ExecutorService
,因此我可以从
Callable
获取返回值,但是您的建议非常有用,我让它完成了我需要它做的事情。谢谢