HttpClient - 从一个InputStream写入多个POST请求

时间:2013-08-12 14:30:12

标签: java http tomcat apache-httpclient-4.x

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

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

是的,我可以简单地将整个InputStream读入网络服务器上的对象并按顺序写入每个商店,但由于我可能会接受非常大的文件我必须将数据写入磁盘,然后为每个商店服务器读回数据,磁盘操作的数量可能会迅速变得令人望而却步。这是我希望避免的实现。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

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

数据必须在哪里,如果不是内存而不是硬盘,那么在哪里?

因此,将传入的数据保留在内存中,直到(如果?)你的内存不足(从不?),然后将其刷新到硬盘驱动器。继续尝试通过将数据发送到商店然后删除数据来清空数据结构。

您可以更轻松地编写ExecutorService代码来处理重新传输数据和清理数据结构,但它不会神奇地解决问题。 :)

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

修改/更改

即使我说过,我也不确定你真的想要一个ExecutorService。我会创建自己的自定义Thread来实际处理它。我将从并发包创建一个Collection,可能是一个包含字节数组(不是字节,字节数组)的LinkedBlockingQueue。然后我将从Thread-> Integer创建一个映射,它在传递数据时保存每个线程进程的当前索引。当所有进度数高于10时(意味着所有线程都发送了前10个块),然后我删除前10个字节数组,并从所有线程的进度中减去10以重置它。